Redis缓存设计
什么是缓存击穿?
缓存击穿是指某个热点数据缓存过期时,⼤量请求就会穿透缓存直接访问数据库,导致数据库瞬间承受的压⼒巨⼤
解决方式常用的有两种
第一种是加互斥锁,当缓存失效后,第一个访问的线程先获取锁然后重建缓存,其余的线程等待或者重试
第⼆种是永不过期策略。缓存项本身不设置过期时间,也就是永不过期,但在缓存值中维护⼀个逻辑过期时间。当缓存逻辑上过期时,返回旧值的同时,异步启动⼀个线程去更新缓存
什么是缓存穿透?
缓存穿透是指查询的数据在缓存中没有命中,因为数据压根不存在,所以请求会直接落到数据库上
常⽤的解决⽅案有两种:第⼀种是布隆过滤器,它是⼀种空间效率很⾼的数据结构,可以⽤来判断⼀个元素是否在集合中
第⼆种是缓存空值。对于不存在的数据,我们将空值写⼊缓存,并设置⼀个合理的过期时间。这样下次相同的查询就能直接从缓存返回,⽽不再访问数据库
什么是缓存雪崩?
缓存雪崩是指在某⼀时间段,⼤量缓存同时失效或者缓存服务突然宕机了,导致⼤量请求直接涌向数据库,导致数据库压⼒剧增,甚⾄引发系统崩溃的现象
第⼀种,⼤量缓存同时过期,解决⽅法是添加随机过期时间
第⼆种,缓存服务崩溃,解决⽅法是使⽤⾼可⽤的缓存集群
第三种,缓存服务正常但并发请求量超过了缓存服务的承载能⼒,这种情况下可以采⽤限流和降级措施
如何保证缓存和数据库的数据⼀致性?
我会采⽤ Cache Aside + TTL 过期机制来保证缓存和数据库的⼀致性
具体做法是读取时先查 Redis,未命中再查 MySQL,同时为缓存设置⼀个合理的过期时间;更新时先更新MySQL,再删除 Redis
这种⽅式简单有效,适⽤于读多写少的场景。 TTL 过期时间也能够保证即使更新操作失败,未能及时删除缓存,过期时间也能确保数据最终⼀致