缓存
Web应用和数据库之间加入Redis缓存可以提高程序并发,但也会带来诸多问题。常见的缓存问题有:缓存雪崩、缓存击穿、缓存穿透。
1. 缓存雪崩¶
1.1. 描述¶
当大量缓存数据在同一时间过期(失效)或者+Redis+故障宕机时,如果此时有大量的用户请求,都无法在+Redis+中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃。
1.2. 原因¶
- 大量数据同时过期
- Redis 故障宕机
1.3. 解决办法¶
大量数据同时过期
- 均匀设置过期时间
- 设置缓存过期时间,加上一个随机数。
- 互斥锁
- 保证同一时间内只有一个请求来构建缓存
- 后台更新缓存
- 频繁地检测缓存是否有效
- 在业务线程发现缓存数据失效后(缓存数据被淘汰),通过消息队列发送一条消息通知后台线程更新缓存
Redis 故障宕机
- 服务熔断或请求限流机制
- 构建 Redis 缓存高可靠集群
2. 缓存击穿¶
2.1. 描述¶
当缓存中的某个热点数据过期了,此时有大量请求访问了该热点数据,就无法从缓存中获取,直接访问数据库,数据库很容易被高并发请求击垮。
2.2. 原因¶
频繁反问过期的热点数据
2.3. 解决办法¶
- 互斥锁
- 保证同一时间内只有一个请求来构建缓存
- 不给热点数据库设置过期时间,后台异步更新或热点数据过期前,提前通知后台线程更新缓存并重新设置过期时间
3. 缓存穿透¶
3.1. 描述¶
当用户访问的数据,既不在缓存中,也不在数据库中。请求来临时先访问缓存,没有数据,然后再访问数据库,也没有数据,如果这类请求大量涌入,数据库压力急剧上升。
3.2. 原因¶
一般有2种情况
- 业务错误操作
- 缓存和数据库数据均被人删除
- 黑客恶意攻击
- 故意使用不存在的数据,大量访问
3.3. 解决办法¶
- 限制非法请求
- 程序中严格校验,判断API请求的合法性。
- 缓存默认值或空值
- 当发生缓存穿透情况,针对业务查询的数据,在缓存中创建默认值或空值
- 使用布隆滤波器快速判断是否存在查询值,避免通过查询数据库判断
- 布隆滤波器基于哈希函数实现查找,高效查询的同时,也存在哈希冲突的情况(误判)。
- 查询布隆滤波器数据存在,并不一定证明数据库中一定存在数据。但查询布隆滤波器数据不存在,数据库中一定不存在对应的数据。