缓存穿透击穿雪崩
0x00 正常缓存的处理流程
正常情况下,服务端收到用户请求,先从缓存中查找相关请求信息,如果缓存命中,则直接返回,如果未命中,则从数据库中查找,如果数据库中存有相关信息则返回结果并更新缓存,如果数据库中也没有,那直接返回空结果。
0x01 缓存穿透
缓存穿透指的是有用户频繁请求一个缓存和数据库中都不存在的资源。就比如我们的用户id
均为正整数,当我们请求一个值为-1
的id
时,如果没有加任何的id
合法性校验机制就会导致缓存穿透。请求这个不存在的id
时,缓存中是肯定没有的,所以指定会造成数据库的查找请求,当不断请求一个不存在的id
时,就会造成过大的数据库压力。
解决方案:
- 可以加入
id
合法性校验机制,当输入不合法的id
时直接返回。 - 可以采用布隆过滤器,布隆过滤器是一种高效的用来快速判断一个值在一个庞大的数据集中是否存在的数据结构。当请求的数据在缓存中不存在需要访问数据库获取数据时,我们可以首先使用布隆过滤器过滤掉在数据库中不存在的数据,如果布隆过滤器返回
true
,即在数据库中存在,然后再进行数据库的查询操作。
0x02 缓存击穿
缓存击穿就是当一个缓存中的key非常地热点,扛着大并发并不断有用户在访问这个key。然后突然这个key从缓存中过期了,这时持续的大并发数据就会突破缓存,直接请求数据库导致数据库压力突增,这就叫缓存击穿。
解决方案:
- 设置缓存永不过期。
- 加互斥锁,当用户请求来袭时,首先从缓存中读取数据,对于读取不到的数据,然后去获取锁,如果得到锁,则从数据库中读取数据并更新缓存,然后释放锁。在高并发来袭时,对于获取不到锁的用户访问,则等待一小段时间,比如10ms,然后再重新走上述流程获取数据。这时一般情况下,这个数据已经被得到锁的访问从数据库重新放到缓存里了,再次获取时就可以直接访问到缓存里面的数据了。
0x03 缓存雪崩
缓存雪崩指的是缓存中的数据大量到达过期时间,而且查询量巨大,引起数据库压力过大导致宕机,和缓存击穿不同的事,缓存击穿指的是其中一条数据到期,缓存雪崩是缓存中很多数据都过期了,很多数据都查不到从而查数据库。
解决方案:
- 随机设置缓存的过期时间,以防同时过期大量缓存数据。
- 将热点数据均匀分布在不同的缓存数据库中。
- 热点数据永不过期。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Shaoqun Liu's Blog!