Redis 可能出现的问题
缓存雪崩
设置不同的过期时间防止同时失效导致数据流直接打到 DB 中间
// 异步存入用户数据提高性能
threadPoolTaskExecutor.execute(()->{
// 设置过期时间使用 保底一天加随机秒数 ,防止同时失效导致缓存雪崩
long expireTime = 60 * 60 * 24 + RandomUtil.randomInt(60 * 60 * 24);
redisTemplate.opsForValue().set(userInfoKey, JsonUtils.toJsonString(findUserByIdRspDTO), expireTime, TimeUnit.SECONDS);
});缓存穿透
设置空值 nil 缓存实现对应的数据打下来的时候没有问题
if (Objects.isNull(userDO)) {
threadPoolTaskExecutor.execute(()->{
// 防止缓存穿透,将 null 数据存入 redis 中间 (设置过期时间为 1-2 min)
// 保底一分钟 + 随机秒数
long expireTime = 60 + RandomUtil.randomInt(60);
redisTemplate.opsForValue().set(userInfoKey, "null", expireTime, TimeUnit.SECONDS);
});
throw new BizException(ResponseCodeEnum.USER_NOT_FOUND);
}- 还能直接设置黑白名单对多次请求的数据进行对应的过滤访问限制操作
缓存击穿
构建多级缓存实现(添加缓存 Caffeine 实现多级缓存操作限制)对应的热点数据请求的削峰以及热点数据失效的问题解决方案
private static final Cache<Long, FindUserByIdRspDTO> LOCAL_CACHE = Caffeine.newBuilder()
.initialCapacity(10000) //初始化 10000 个条目
.maximumSize(10000) // 最大容量为 10000 个条目
.expireAfterWrite(1, TimeUnit.HOURS) // 设置过期时间在写入之后一个小时
.build();