[版权申明] 非商业目的注明出处可自由转载
出自:shusheng007
概述
由于云服务的快速发展,分布式已经成为当今大中型IT架构事实标准。而分布式缓存也基本成为其中的基础设施,在此方面Redis已经获得全面胜利。
为什么要使用缓存
主要思想还是以空间换时间,为了节约CUP及IO资源,进而提高系统的吞吐量及响应速度。如果你的CUP及IO资源完全足够,那就没有必要引入缓存,因为任何事物都具有两面性,缓存也一样。
缓存常见问题
在大中型分布式系统中,数据库非常容易成为整个系统的瓶颈,所以现在基本都会以Redis构建挡在数据库之前的那层缓存,以便某些请求可以不经过数据库直接在缓存层返回。但如果不做任何保护,有时缓存层仍然挡不住来袭之敌,最后量大了就把数据库打崩溃了。下面就列举几种情况。
缓存穿透
听听这名字,太吓人了
- 什么是缓存穿透
当一个请求过来,缓存与数据库中都不存在要请求的数据,所谓的穿透了,因为不仅是缓存层,就连数据库层都穿过去了,所以说穿透了。一个两个没事,就怕瞬时大量这样的请求,那数据库就死给你看了。
- 场景及解决方案
场景1:由正常业务引起。正常业务中刚好就是有这种数据库中没有数据的操作,这种
方案:给这样的key设置null作为缓存,然后设置一个很短的缓存过期时间
场景2:外部的恶意攻击。有人专门构造你缓存与数据库不存在数据的请求来恶意攻击你。
方案:这种场景第一种解决方案可能无能为力了,因为攻击者可能构建大量随机不重复的key去获取数据。这种情况可以使用布隆过滤器
布隆过滤器(英语:Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中
如果布隆过滤器判定某个 key 不存在,那么就一定不存在,如果判定某个 key 存在,那么很大可能是存在(存在一定的误判率)
缓存击穿
- 什么是缓存击穿
这里的缓存击穿特指缓存中的某个热点数据失效,请求直接打到了数据库上。也就是说缓存没有命中,直接被击穿了,但是数据库中是存在数据的。
- 场景及解决方案
场景:
有的同学要问了:既然数据库有值,访问数据库后将数据回填到缓存不就好了?你说的很对,所以缓存击穿专门描述的是热点数据被击穿造成的问题。热点数据会存在存在大量并发,假设一下来了10000个不分先后的请求去访问同一条数据,关键缓存中还没有,那么就直接到了数据库,那么数据库扛不住就崩溃了。
方案:
由于是因为并发访问失效的热点数据的缓存造成的,所以就要从这并发与失效两方面解决。
如果从并发的角度解决的化,我们很容易想到加锁。当第一个请求到达的时候就加锁,其他请求都等着,第一个请求从数据库中获取数据后就会回填到缓存中的,然后释放锁。那接下来的请求就不用加锁了,因为此时缓存中已经存在数据了。
如果从失效角度解决的化,我们很容易想到让热点数据“不失效”,永不失效实际包含两层意思:
-
物理不过期,针对热点key不设置过期时间
-
逻辑过期,由程序员负责更新数据。例如把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建
缓存雪崩
这名字更唬人,我第一次看见这个名词时联想到的就是天崩地裂,是不是缓存服务器崩了?后来证明有时望文生义也不是全然不对,至少缓存服务器崩了确实会导致缓存雪崩,哈哈。。。
- 什么是缓存雪崩
缓存雪崩是指由于缓存中大批缓存数据同一时刻失效,那么访问这些数据的请求都会击穿缓存,直接到达数据库,数据库死给你看的情形。
- 场景及解决方案
场景1:缓存服务器宕机了,那肯定就满足大批缓存同时失效的情形啦。
方案: 不要让它宕机。例如如何保证Redis高可用性有很多种方式,最可靠的当然是集群部署,自己查询相关资料即可。
场景2:设置了大量同一时刻失效的缓存
方案: 使缓存均匀过期,设置不同的过期时间,让缓存失效的时间尽量均匀。
总结
你get到了吗?同时我又一次惊叹于汉语的博大精深,自从喊出祖国有力量,民族有信仰,人民有希望的口号后,文化就自信了很多。
文章评论