1.Redis面试题-缓存穿透,缓存击穿,缓存雪崩
1 穿 透: 两边都不存在(皇帝的新装) (返回空值)(互斥锁)(黑名单) (布隆过滤器)
2 击 穿 :一个或多个热点的key失效了,这时大量的并发请求直接到达数据库. (提前预热)
3 雪崩 :大量key同时失效 (避免大量的key同一时间失效,错峰)
++【大厂面试题】缓存穿透清晰讲解!看完不会,你来打我 # 编程 # java # java面试 # 面试题 # 开发 https://v.douyin.com/irdtam1Q/ 复制此链接,打开Dou音搜索,直接观看视频!++
2.Spring是如何集成Redis的?
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
3.高级封装
4.Redis配置
Spring.Redis常用配置参数有哪些。
XML
# Redis服务器地址
spring.redis.host=10.1.30.222
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
#spring.redis.password=
## 连接超时时间(毫秒)
spring.redis.timeout=30000
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active=8
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle=8
# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle=1
#连接池中最大空闲等待时间,3s没有活干的时候直接驱逐该链接
spring.redis.lettuce.pool.min-evictable-idle-time-millis = 3000
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait=-1
5.StringRedisTemplate
String
java
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final String key = "zhengzhou";
public void test() {
stringRedisTemplate.opsForValue().set(key, "我的家乡", 30, TimeUnit.SECONDS);
String value = stringRedisTemplate.opsForValue().get(key);
System.out.println(value);
}
Hash
java
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final String key ="zhouxingxing";
public void test(){
stringRedisTemplate.opsForHash().put(key,"20220325","郑州");
stringRedisTemplate.opsForHash().put(key,"20220326","洛阳");
List<Object> values = stringRedisTemplate.opsForHash().values(key);
for (Object value:values){
System.out.println(value);
}
}
List
java
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final String key ="onewayroad";
void test(){
stringRedisTemplate.opsForList().leftPush(key,"周星星");
stringRedisTemplate.opsForList().leftPush(key,"张敏");
stringRedisTemplate.opsForList().leftPush(key,"李大锤");
String value = stringRedisTemplate.opsForList().rightPop(key);
System.out.println(value);
}
}
@Test
void test6() {
// 如果一些原生命令,spring 没有给我们封装,redisTemplate.execute(new RedisCallback)
while (true){
System.out.println("开始一轮监听");
List<byte[]> rawResults = redisTemplateProduct.execute(new RedisCallback<List<byte[]>>() {
@Override
public List<byte[]> doInRedis(RedisConnection connection) throws DataAccessException {
return connection.bRPop(5,"product.hot".getBytes());
}
});
if(ObjUtil.isNotEmpty(rawResults)){
byte[] rawKey = rawResults.get(0);
byte[] rawValue = rawResults.get(1);
Product product = (Product)redisTemplateProduct.getValueSerializer().deserialize(rawValue);
System.out.println(product);
}
}
Set
java
@Component
public class SetDemo {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final String zhouxingxing ="zhouxingxing";
private final String zhangmin = "zhangming";
public void test(){
//添加周星星同学感兴趣的科目
stringRedisTemplate.opsForSet().add(zhouxingxing,"语文");
stringRedisTemplate.opsForSet().add(zhouxingxing,"数学");
stringRedisTemplate.opsForSet().add(zhouxingxing,"数学");
//添加张敏同学感兴趣的科目
stringRedisTemplate.opsForSet().add(zhangmin,"数学");
stringRedisTemplate.opsForSet().add(zhangmin,"英语");
//获取两位同学共同感兴趣的科目
Set<String> values = stringRedisTemplate.opsForSet().intersect(zhouxingxing, zhangmin);
System.out.println("周星星和张敏共同感兴趣的科目为:");
for(String value : values){
System.out.println(value);
}
}
}
ZSet
java
@Component
public class ZSetDemo {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final String key ="zhouxingxing";
public void test(){
//添加周星星同学成绩
stringRedisTemplate.opsForZSet().add(key,"语文",98);
stringRedisTemplate.opsForZSet().add(key,"数学",87);
stringRedisTemplate.opsForZSet().add(key,"英语",75);
//获取分数最高的成绩
ZSetOperations.TypedTuple<String> values = stringRedisTemplate.opsForZSet().popMax(key);
//打印值
System.out.println("周星星最好成绩科目是:"+values.getValue());
System.out.println("周星星最好成绩:"+values.getScore());
}
}
6.RedisTemplate<T,V>泛型约束
6.1泛型约束的使用
java
@Component
public class RedisTemplateDemo {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Resource
private RedisTemplate<String, User> redisTemplate;
@Resource(name="redisTemplate")
private ValueOperations<String,User> valueOperations;
private final String key = "useris#01";
public void test() {
User user = User.builder().id(1).name("李四").build();
redisTemplate.opsForValue().set(key,user );
User value = redisTemplate.opsForValue().get(key);
valueOperations.set(key,user );
User value2 = valueOperations.get(key);
System.out.println(value);
}
}
6.2乱码的问题
java
JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
byte[] serialize = serializer.serialize("user.01");
System.out.println(new String(serialize));
6.3自定义序列化工具
java
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
// 序列化的时候,自动推断类型,将类型信息作为属性写入JSON
// 反序列化时候,根据类型的全类名,序列化成对应的对象实例
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//普通key序列化工具
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash 小key 序列化工具
template.setHashKeySerializer(RedisSerializer.string());
template.setHashValueSerializer(jackson2JsonRedisSerializer);
return template;
}
}
7. 直接使用ListOperations、ValueOperations、SetOperations、ZSetOperations、HashOperations接口
在Spring Data Redis中,提供了丰富的模板操作接口,
如
ListOperations
、ValueOperations
、SetOperations
、ZSetOperations
、HashOperations
这些都是
RedisTemplate
的子接口,用于针对不同类型的Redis数据结构进行操作