概述
[原文链接 - 缓存如何做到高可用]
分布式缓存的高可用方案(缓存穿透、缓存击穿、缓存雪崩)
主要选择的方案有客户端方案、中间代理层方案和服务端方案三大类:
客户端方案就是在客户端配置多个缓存的节点,通过缓存写入和读取算法策略来实现分布式,从而提高缓存的可用性。
中间代理层方案就是在应用代码和缓存节点之间增加代理层,客户端所有的写入和读取的请求都通过代理层,而代理层中会内置高可用策略,帮助提升缓存系统的高可用。
服务端方案就是redis 2.4版本后提出的Redis Sentinel方案。
掌握这些方案可以帮助你抵御部分缓存节点故障导致的缓存命中率下降的影响
一般来讲,分片算法常见的及时Hash分片算法和一致性Hash分片算法两种。
还有主备、分布式缓存的选项
1. 缓存穿透
[描述]
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
[解决方案]
接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
[缓存击穿解决方案]
在缓存使用的场景中,缓存KEY值失效的风暴(单个KEY值失效,PUT时间较长,导致穿透缓存落到DB上,对DB造成压力)。可以采用 布隆过滤器 、单独设置个缓存区域存储空值,对要查询的key进行预先校验 、缓存降级等方法。
缓存穿透业内的解决方案已经比较成熟,主要常用的有以下几种:
[bloom filter]:类似于哈希表的一种算法,用所有可能的查询条件生成一个bitmap,在进行数据库查询之前会使用这个bitmap进行过滤,如果不在其中则直接过滤,从而减轻数据库层面的压力。guava中有实现BloomFilter算法。
[空值缓存]:一种比较简单的解决办法,在第一次查询完不存在的数据后,将该key与对应的空值也放入缓存中,只不过设定为较短的失效时间,例如几分钟,这样则可以应对短时间的大量的该key攻击,设置为较短的失效时间是因为该值可能业务无关,存在意义不大,且该次的查询也未必是攻击者发起,无过久存储的必要,故可以早点失效。
2. 缓存雪崩
在普通的缓存系统中一般例如redis、memcache等中,我们会给缓存设置一个失效时间,但是如果所有的缓存的失效时间相同,那么在同一时间失效时,所有系统的请求都会发送到数据库层,db可能无法承受如此大的压力导致系统崩溃。
[解决方案]
加锁排队、设置过期标志更新缓存、设置过期标志更新缓存、二级缓存(引入一致性问题)、预热、缓存与服务降级
3. 缓存击穿
缓存击穿实际上是缓存雪崩的一个特例,缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。击穿与雪崩的区别即在于击穿是对于某一特定的热点数据来说,而雪崩是全部数据。
[解决方案]
-双重校验(Dubbo Check)类似线程安全的懒汉单例模式实现,保证只会有一个线程去访问数据库
最后
以上就是欢喜高山为你收集整理的如何设计一个高可用的缓存系统的全部内容,希望文章能够帮你解决如何设计一个高可用的缓存系统所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复