Redis实战(八):面试常问:击穿,穿透,雪崩,分布式锁,API(jedis,luttce,springboot:lowhigh level)

    技术2022-07-10  148

    缓存击穿

    作为缓存,受到内存大小限制,可能:

    key 超过了过期时间key 被 LRU LFU 清掉了

    因为某些 key 不在 redis 里面了,大量并发来找这个 key 的时候,这时候客户端去直接请求数据库,这就是击穿。

    这个问题怎么解决? 只要发现某个key不存在,就让所有对这个key的请求去抢一把锁。也就是说, 让第一个找key的请求,执行一个setnx,类似于放一把锁。只有获得锁的人才能去数据库查,其他的请求让它们失败,sleep等待几秒钟之后,重新去 redis 取数据。

    这会存在一个问题: 1、如果第一个拿到锁的人挂了,别人也拿不到锁,这样就死锁了。可以设置锁的过期时间来避免这个问题。 2、由于我设置了过期时间,可能会发生这样的情况:拿到锁的人没挂,但是可能由于网络拥塞或者数据库拥塞,锁超时了,又有一个人拿到这个锁,又去数据库取,更加拥塞了。 针对这个问题,可以开启多个线程,一个线程去库里取数据,另一个线程去给锁的超时时间延长。这样会让代码逻辑变得复杂。 3、像上面这样,你自己去实现分布式协调很麻烦。因此我们引入Zokeeper,这个以后再讲~

    缓存穿透

    从业务接收查询的,是你系统里面根本不存在的数据。这就是缓存穿透。

    怎么解决? 1、使用布隆过滤器

    你可以在客户端中包含布隆过滤器的算法你可以在客户端只包含算法,在redis中存放bitmap你可以直接在redis中集成布隆模块:RedisBloom模块

    布隆过滤器的缺点:只能增加,不能删除,如果你的业务删除了数据库中的某条数据,无法在布隆过滤器中删除这个key 解决方式:你可以使用布谷鸟过滤器等其他支持删除操作的过滤器,或者设置一个空 key

    缓存雪崩

    和击穿有些类似,都是后面有数据的情况。 大量 key 同时失效,间接造成大量的访问到达 DB

    怎么解决? 要考虑两种情况: 1、每天都要更新数据的情况,例如每天零点要刷新缓存。这时候可以依赖击穿的解决方案。或者在业务层加一个小延时:判断如果是零点就延时,随机sleep几秒,这样不会把流量一大波流量同时放过来。 对于能够提前预知的时点数据,比如京东双11的页面样式、图片等,可以提前推到客户端本地,到双11零点的时候直接切换即可。 2、与时点性无关(并不需要在某个时间刷新缓存)的话,可以设置随机过期时间。

    Redis做分布式锁

    1、setnx 2、过期时间 3、多线程(守护线程)延长过期时间

    可以使用j ava Sedisson API 也可以用 zookeeper 做分布式锁,这样是最容易的。虽然zookeeper没有redis快,但是比redis能够加强准确性。

    API

    redis 支持大多数语言,因此它二进制安全保证了数据在跨语言的时候不会出问题 可以查看所有配置项

    spring redis 文档

    Processed: 0.019, SQL: 8