banner
Tenifs

Tenifs

雄关漫道真如铁,而今迈步从头越。
github
follow
zhihu
email

Redis 缓存雪崩、缓存击穿、缓存穿透的解决方案

缓存雪崩#

缓存雪崩:当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,无法在 Redis 中处理,那么这些请求将会直接访问数据库,从而导致数据库压力骤增,严重的话会导致数据库崩溃宕机,进而导致整个系统崩溃。

解决方案:

  • 避免为大量的数据设置成同一个过期时间,我们可以在设置过期时间时添加一个随机数,这样就可以保证数据不会在同一个时间过期了。
  • 互斥锁,如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一个时间内只有一个请求来构建缓存(从数据库读取数据,再将数据更新到 Redis),当缓存构建完成后,再释放锁。未能获取到互斥锁的请求,要么等待锁释放后,重新读取缓存,要么直接返回空值或者默认值。实现互斥锁时,要设置超时时间,不然某个请求拿到锁后,如果请求发生意外情况而一直阻塞,一直不释放锁,这时其他请求不能拿到锁,整个系统就会出现无响应的现象。
  • 后台更新缓存,业务线程不再负责更新缓存,缓存不必设置有效期,让缓存 “永久有效”,并将更新缓存的工作交由后台线程定时更新。

缓存击穿#

缓存击穿:如果缓存中的某些热点数据过期了,此时大量的请求访问这些热点数据,就无法从缓存中读取,进而直接访问数据库,导致数据库被高并发请求冲垮。

解决方案:

  • 互斥锁,保证同一时间内只有一个线程更新缓存,未能获取到互斥锁的请求,要么等待锁释放,要么直接返回空值或默认值。
  • 不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据要过期前,提前通知后台线程更新缓存并重新设置过期时间。

缓存穿透#

缓存穿透:当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时失效,再去访问数据库,发现数据库中也没有这些数据,没办法构建缓存为后续的请求服务。当有大量这样的请求时,数据库的压力会骤增,进而导致数据库崩溃。

解决方案:

  • 非法请求判断:在请求入口处加入请求参数校验,检查参数是否合理有效,如果是非法参数,直接返回错误,避免进一步访问缓存和数据库。
  • 缓存空值或默认值,针对某些要查询的数据,在缓存中设置一个空值或默认值,这样后续的请求可以直接从缓存中读取到空值或者默认值,返回给应用程序,而不会进一步查询数据库。
  • 布隆过滤器:当用户请求到来时,可以通过查询布隆过滤器来快速判断数据是否存在,如果不存在,就不用再查询数据库了,这样就能保证数据库正常运行。
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。