redis 缓存设计

     1、 缓存穿透:查找一个不存在的key 数据, 缓存层和存储层都不会命中,将导致不存在的数据每次请求都要到存储层去查询,失去缓存保护DB 的意义。

      解决方案:有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器(不了解的可以看这里),将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。PS: 布隆过滤器具有一定的误判率,对于零容忍的判断是不可取的。另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数 据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。PS: 缓存短时间是让其过期自动删除,释放缓存空间。

 

      2、缓存雪崩 :在高并发,大请求量上来的时候,所有的缓存key 集体失效,所有的请求都堆到了数据存储层。缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。  

      解决方案:缓存失效时的雪崩效应对底层系统的冲击非常可怕。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线 程(进程)写,从而避免失效时大量的并发请求落到底层存储系统上。这里分享一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。 还有方案是:加锁排队. 限流-- 限流算法. 1.计数 2.滑动窗口 3.  令牌桶Token Bucket 4.漏桶 leaky bucket [1]

关键字: 时间岔开,确保大家的key不会落在同一个expire点上。

      3、缓存击穿

 缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

      解决方案:导致问题的原因是同一时间查,同一时间写缓存,导致并发下缓存也没用,所以考虑使用单线程等方法将写缓存保证只有一个去查了写,其他的使用缓存。

业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。 
SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值