越不懂的越爱装
大家都同等:IT世界没有难不难,只有是否了解过
挑战目录
如何在Springboot中使用Redis进行缓存
依赖及yml配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
# 配置redis以及cache
spring:
redis:
host: 127.0.0.1
port: 6379
password:
timeout: 10000 #连接超时时间
缓存配置:
- 开启基于注解的缓存
@EnableCaching - 设置缓存数据时value序列化、key生成 策略
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(factory);
// 创建json序列化对象
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 设置key序列化String
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 设置value序列化 json
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
// 设置hash key序列化String
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// 设置hash value 序列化json
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
// 初始化redis完成序列化的方法
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
-
配置缓存管理器
@Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() //设置缓存默认超时时间 30分钟 //.entryTtl(Duration.ofMillis(30)) .disableCachingNullValues() // 设置key序列化 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); return RedisCacheManager.builder(factory).cacheDefaults(cacheConfiguration).build(); }
缓存操作
-
设置缓存
@Cacheable: 有缓存就读缓存,没有才执行将返回值设置到缓存中@Cacheable(value = "userCache", key = "111") //对应key userCache::111 @PostMapping("/saveTest") public String saveTest() { log.error("----查询数据库----"); return "查询数据库"; }
-
更新缓存
@CachePut:保证方法被调用,并且将返回结果缓存到Redis
@PostMapping("/updateTest") @CachePut(value = "userCache", key = "111") //对应key userCache::111 public String updateTest() { log.error("----更新缓存----"); return "删除缓存->1"; }
-
删除缓存
@CacheEvict:删除对应缓存
@PostMapping("/deleteTest") @CacheEvict(value = "userCache", key = "111") //对应key userCache::111 public String deleteTest() { log.error("----删除缓存----"); return "删除缓存"; }
上面的注解有匹配上的value和key相同的时候,表示操作同一个key
上面的注解内可以添加的变量都有:- value: 缓存的名称 ,@Cacheable(value=”mycache”)、@Cacheable(value={”cache1”,”cache2”}
- key:缓存的 key,可以为空 。支持SpEL 表达式编写
- condition:缓存的条件,支持SpEL 表达式编写,返回true表示进行上述三个注解的操作
- unless:否定缓存,当条件为TRUE时,就不会缓存。支持SpEL 表达式编写
CacheEvict 专有变量:
- allEntries:是否清空所有缓存内容,缺省为 false。
- beforeInvocation:是否在方法执行前就清空,缺省为 false(缺省时,如果执行异常,则不会清空缓存)。
SpEL表达式
- 当前被调用的方法名:#root.methodname
- 当前被调用的方法:#root.method.name
- 当前被调用的目标对象实例: #root.target
- 当前被调用的目标对象的类: #root.targetClass
- 当前被调用的方法的参数列表: #root.args[0]
- 当前方法调用使用的缓存列表: #root.caches[0].name
- 当前被调用的方法的参数的内部变量: #参数.内部变量
CachePut专有SpEL表达式:
- 方法执行后的返回值:#result
上述表达式中
- root是默认的,使用时可以省略
- 使用方法参数时可以直接使用"#参数名"或者"#p参数的index"
@Cacheable(value=“users”, key="#id")
@Cacheable(value=“users”, key="#p0")
条件表达式支持的运算符
<,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne,+,- ,* ,/,%,^,&&,||,!,and,or,not,between,instanceof,?: (ternary),?: (elvis),正则表达式, ?.,?[…],![…],^[…],$[…]
查看缓存的数据(客户端命令行)
- 查看当前缓存的所有key
keys * - 统计当前存储的所有key
info Keyspace - 查看对应key的value时,中文不显示16进制而是显示中文
启动redis-cli时后面加上参数 --raw
常见面试题
-
缓存雪崩,缓存穿透,缓存击穿
缓存雪崩:在同一时间点大面积失效(请求会落到数据库上去)。
解决方案:互斥锁缓存穿透:缓存和数据库中都没有数据(一般来自于攻击数据库的时候,因为一般数据库是会有数据的)。
解决方案:采用布隆过滤器(),缓存击穿:缓存中没有,但是数据库中有(缓存过期或其他原因)。
解决方案:热点数据设置永远不过期(缺点:)。
-
秒杀系统实现
-
过期键删除策略
-
redis事务实现
-
Redis线程模型,单线程为什么这么快
-
主从赋值核心原理
-
redis集群方案
-
CAP理论,BASE理论
-
负载均衡算法,类型
-
Session共享方案
-
如何做到Redis和数据库数据一致性
网友评论