Redis-更新策略,缓存穿透,缓存雪崩,缓存击穿
1.缓存更新 策略
- 淘汰策略
- 超时剔除
- 主动更新
- 更新策略:先修改数据库还是先删除缓存 结论:先修改数据库,因为缓存的操作比较快,容易产生数据不一致
- 更新缓存还是删除缓存?
2.缓存穿透
客户端请求的数据在缓存和数据库中都不存在,这些请求会访问到数据库
解决方式
- 缓存空值:额外内存空间; 短期造成数据不一致
- 布隆过滤器,把数据转换成二进制的情况存储,即使在布隆过滤其中存在,实际上也可能不存在,因此有一定的风险
- 增加id复杂度,主动预防缓存穿透情况
- 增强用户的权限
3.缓存雪崩
是指在同一时间大量的缓存失效或redis服务器宕机,导致大量的请求同时访问数据库。
解决方式:
- 设置缓存key随机的TTL
- 增加redis服务高可用
- 大量的请求限流
- 多级缓存,nginx,jvm,浏览器等
- 设置热点数据不过期
4.缓存击穿
缓存击穿也叫热点Key问题,一个被高并发访问并且缓存业务重建复杂的key失效了,导致大量的key访问数据库带来冲击。
解决方式:
-
互斥锁
-
逻辑过期
-
热点数永不过期
-
限流熔断
缓存击穿-互斥锁代码实现:
/** 缓存数据KEY */private final String CACHE_SHOP_KEY = "CACHE_SHOP_KEY:";/** 缓存互斥锁KEY */private final String CACHE_SHOP_LOCK_KEY = "CACHE_SHOP_LOCK_KEY:";@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** redis缓存* 缓存击穿-互斥锁版本* @param bookId*/private BooksVo tryCacheMutex(Long bookId) {// RedisKeyString cacheKey = CACHE_SHOP_KEY + bookId;// 1.从Redis查询商铺缓存// 获取缓存数据String contentBook = stringRedisTemplate.opsForValue().get(cacheKey);// 2.判断缓存是否命中if (StringUtils.isNotBlank(contentBook)){// 3.1缓存命中 直接返回结果return JSONUtil.toBean(contentBook, BooksVo.class);}BooksVo booksVo = null;try {// 3.2缓存未命中,尝试获取互斥锁if (BooleanUtil.isFalse(tryLock(bookId))) {// 4.1获取互斥锁失败,尝试重试Thread.sleep(50);return tryCacheMutex(bookId);}// 4.2 获取互斥锁成功// 4.3 再次检测缓存是存在 doubleCheckcontentBook = stringRedisTemplate.opsForValue().get(cacheKey);if (StringUtils.isNotBlank(contentBook)){return JSONUtil.toBean(contentBook, BooksVo.class);}// 4.4 查询数据库,缓存重建booksVo = this.queryById(bookId);// 模拟缓存重建延迟Thread.sleep(200);String jsonBook = JSONUtil.toJsonStr(booksVo);stringRedisTemplate.opsForValue().set(cacheKey,jsonBook);} catch (InterruptedException e) {throw new RuntimeException();}finally {// 5.释放锁stringRedisTemplate.delete(CACHE_SHOP_LOCK_KEY + bookId);}return booksVo;}/*** 获取互斥锁*/public boolean tryLock(Long bookId){// redis: set xxx value nx ex 10 添加锁nx是互斥,ex设置过期时间Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent(CACHE_SHOP_LOCK_KEY + bookId, "1", 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(aBoolean);}
后期更新逻辑过期的实现方式