再读缓存三剑客:穿透,雪崩,击穿

1.缓存穿透

高并发场景下,大量结果为null的请求打入系统。这样会迅速消耗尽数据库连接数资源,最终导致数据库连接不可用

解决方法:

  1. 增加请求校验:如何请求的id如果是long,如果发过来的id不是long那就直接返回
  2. 布隆过滤器:检索一个元素是否在一个集合中,通过hash函数将一个元素映射成位阵列(bit array)的一个点。后续查询我们只需要看这个点是不是1,就知道集合中有没有这个元素了
    1. 如果使用布隆过滤器,我们需要考虑缓存预热,将所有待查询的id提前存入过滤器,后续每次添加数据也需要将新的id存入过滤器。
    2. 一般我们通过guava或者redisson实现
  3. 缓存空/null值:容易被故意增大redis压力,处理不好会有数据不一致的情况。使用这个方法时一定要给key设置一个短暂的过期时间

 

2.缓存雪崩

高并发场景下,大量key同时失效导致大量请求同时涌入数据库,迅速耗尽数据库连接数导致其不可用

解决方法:

  1. 对同一类型key设置不同的过期时间
  2. 缓存预热:通过定时任务定时的将数据库的数据同步到缓存中
  3. 加同步锁

 

3.缓存击穿

高并发场景下,热点key突然失效,大量热点key突然打入数据库,连接数耗尽不可用

解决方法

  1. 同步锁
  2. 热点key取消过期时间

 

分布式同步锁解决雪崩与击穿问题

用redisson,redisson通过redis实现了一些java的接口方法,这样的作用是依靠redis作为中间件,摆脱了集群环境下jvm的限制:例如当我们使用锁的时候,如果在单机环境下java内提供的synchronized和lock足够用;但是如果在分布式环境下的高并发场景会因为jvm之间的隔离无法达到预期。

redisson解决缓存雪崩与击穿:通过redisson提供的RLock,可以防止分布式情况下多节点同时涌入数据库,在一个节点更新完毕后其他节点可以直接使用该节点更新完毕后的数据

        //未命中缓存,使用redisson锁减少数据库IO
        RLock lock = redissonClient.getLock("coursepublishQuery::" + courseId);
        lock.tryLock();
        try {
            //从数据库中查询数据并添加至redis中
        } finally {
            lock.unlock();
        }

 

posted @   天启A  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示