美文网首页
Redis 击穿、穿透、雪崩和分布式锁

Redis 击穿、穿透、雪崩和分布式锁

作者: Robin92 | 来源:发表于2020-04-06 22:34 被阅读0次

    击穿

    前提:当 Redis 做缓存时,挡在 DB 之前,当有查数据请求时,Redis 有的话直接返回,从而避开请求 DB,没有时再去请求 DB,请求回来后缓存在 Redis 中。

    击穿:Redis 缓存刚刚过期的时候有大量请求同一查询过来,就会直接 击穿 去访问 DB。

    解决方法:

    • 在 Redis 中上锁(setNX + expire),只有获得锁的人才能去请求。
    • 后面请求的没获得锁,等待(睡眠)后再取。
    • 请求 DB 者,请求回来后,将数据放到 Redis 中。

    但有例外:如果 Expire 太小怎么办?
    解决:请求者开启另一个线程,如果请求 DB 时间过长,则更新 Expire。

    穿透

    情景:Redis 作为缓存时,业务请求的是系统根本不存在的东西,它在 Redis 中找不到,在数据库中也找不到,这样并发的请求过来的时候,就会造成穿透。

    解决:可以在客户端加算法,直接返回无结果;也可以用 布隆过滤器 将可查询的字段映射到 bitmap 中。

    缺点:布隆过滤器不支持删除,所以可以换一个过滤器,如布谷鸟。

    雪崩

    情景:Redis 在做缓存时,大量的 Key 同时失效(比如零点 key 要换成第二天的),此时有大量并发都在访问 DB,这种情况叫雪崩。

    解决:可以的话可以均匀分布过期时间(有些情景是到时间点必须换);可以用击穿的方案,第一个请求者加锁并查回数据缓存下来;还可以在客户端加判断在零点延时。

    综上,它们的区别主要在:击穿是一个点;穿透是本来就不存在的一组数据;雪崩是一批数据在更换没有阻挡住。

    分布式锁:RedLock

    基础:

    • SetNx
    • Expire
    • 守护线程延长过期时间

    步骤,假如有 N 个 Redis 节点:

    • 获取当前时间
    • 按顺序去 N 个节点获取锁(访问的超时时间应远小于锁的过期时间)
    • 获取 N/2+1 个锁成功就认为成功
    • 成功后更新锁的时间。(最初锁的有效时间减去获取锁中间消耗的时间)
    • 失败后立即释放成功上锁节点的锁

    其他方式:换 Zookeeper

    相关文章

      网友评论

          本文标题:Redis 击穿、穿透、雪崩和分布式锁

          本文链接:https://www.haomeiwen.com/subject/bnobphtx.html