缓存穿透、缓存击穿、缓存雪崩

0x00 正常缓存的处理流程

正常情况下,服务端收到用户请求,先从缓存中查找相关请求信息,如果缓存命中,则直接返回,如果未命中,则从数据库中查找,如果数据库中存有相关信息则返回结果并更新缓存,如果数据库中也没有,那直接返回空结果。

0x01 缓存穿透

缓存穿透指的是有用户频繁请求一个缓存和数据库中都不存在的资源。就比如我们的用户id均为正整数,当我们请求一个值为-1id时,如果没有加任何的id合法性校验机制就会导致缓存穿透。请求这个不存在的id时,缓存中是肯定没有的,所以指定会造成数据库的查找请求,当不断请求一个不存在的id时,就会造成过大的数据库压力。

解决方案:

  1. 可以加入id合法性校验机制,当输入不合法的id时直接返回。

  2. 可以采用布隆过滤器,布隆过滤器是一种高效的用来快速判断一个值在一个庞大的数据集中是否存在的数据结构。当请求的数据在缓存中不存在需要访问数据库获取数据时,我们可以首先使用布隆过滤器过滤掉在数据库中不存在的数据,如果布隆过滤器返回true,即在数据库中存在,然后再进行数据库的查询操作。

0x02 缓存击穿

缓存击穿就是当一个缓存中的key非常地热点,扛着大并发并不断有用户在访问这个key。然后突然这个key从缓存中过期了,这时持续的大并发数据就会突破缓存,直接请求数据库导致数据库压力突增,这就叫缓存击穿。

解决方案:

  1. 设置缓存永不过期。

  2. 加互斥锁,当用户请求来袭时,首先从缓存中读取数据,对于读取不到的数据,然后去获取锁,如果得到锁,则从数据库中读取数据并更新缓存,然后释放锁。在高并发来袭时,对于获取不到锁的用户访问,则等待一小段时间,比如10ms,然后再重新走上述流程获取数据。这时一般情况下,这个数据已经被得到锁的访问从数据库重新放到缓存里了,再次获取时就可以直接访问到缓存里面的数据了。

0x03 缓存雪崩

缓存雪崩指的是缓存中的数据大量到达过期时间,而且查询量巨大,引起数据库压力过大导致宕机,和缓存击穿不同的事,缓存击穿指的是其中一条数据到期,缓存雪崩是缓存中很多数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  1. 随机设置缓存的过期时间,以防同时过期大量缓存数据。

  2. 将热点数据均匀分布在不同的缓存数据库中。

  3. 热点数据永不过期。