当前位置: 首页 > 科技观察

解决Redis缓存雪崩的六大法宝,看完记得收藏

时间:2023-03-20 23:25:16 科技观察

Redis雪崩缓存层承载大量请求,有效保护存储层。但是,如果缓存大量失效或者缓存整体无法提供服务,导致大量请求到达存储层,则会增加存储层的负载。这就是缓存雪崩的场景。解决缓存雪崩,可以从以下几个方面入手。1、保持缓存层的高可用。使用Redis哨兵模式或Redis集群部署方式。即使个别Redis节点下线,整个缓存层仍然可以使用。此外,Redis还可以部署在多个机房,这样即使机房宕机,依然可以实现缓存层的高可用。2、限流降级组件,不管是缓存层还是存储层,都会有出错的概率,都可以看成是资源。作为一个并发量很大的分布式系统,如果某个资源不可用,可能会导致所有线程在获取这个资源时出现异常,导致整个系统不可用。降级在高并发系统中是很正常的。比如在推荐服务中,如果个性化推荐服务不可用,可以降级补充热点数据,以免导致整个推荐服务不可用。常见的限流降级组件如Hystrix、Sentinel等3.缓存不过期Redis中存储的key是永不过期的,所以不会出现大量缓存同时失效的问题,但是之后Redis需要更多的存储空间。4、优化缓存过期时间在设计缓存时,为每个key选择合适的过期时间,避免大量key同时失效,造成缓存雪崩。5.使用mutex重建缓存在高并发场景下,为了避免大量请求同时到达存储层查询数据重建缓存,可以使用mutex控制,比如如在缓存层根据key查询数据,当缓存层命中时,锁定key,然后从存储层查询数据,将数据写入缓存层,最后释放锁。如果其他线程发现获取锁失败,让该线程休眠一段时间再尝试。对于锁的类型,如果是在单机环境下,可以使用Java并发包下的Lock,如果是在分布式环境下,可以使用分布式锁(Redis中的SETNX方式)。在分布式环境下,Redis分布式锁用于实现缓存重构。优点是设计思路简单,保证数据一致性;缺点是代码复杂度增加,可能导致用户等待。假设在高并发下,在缓存重建时锁定key,如果当前有1000个并发请求,其中999个被阻塞,就会导致999个用户请求阻塞等待。6.异步重建缓存。该方案下采用异步策略构建缓存。线程会从线程池中获取线程异步构建缓存,这样所有的请求都不会直接到达存储层。该方案中,每个Rediskey维护逻辑超时时间,当逻辑超时时间小于当前时间时,说明当前缓存失效,应该更新缓存,否则说明当前缓存是不无效,直接返回缓存中的值。例如在Redis中设置key过期时间为60分钟,在对应的value中设置逻辑过期时间为30分钟。这样当key达到30分钟的逻辑过期时间时,可以异步更新这个key的缓存,但是在更新缓存期间,老的缓存还是可用的。这种异步重建缓存的方式可以有效防止大量key同时失效。