## 缓存击穿
**查询缓存中失效的 key**。大量的请求同时查询一个 key 时,此时这个 key 正好失效了,就会导致大量的请求都落到数据库。
:-: ![缓存击穿](https://img.kancloud.cn/7f/95/7f95be7ad023fd913f6f9dba6c0b3a98_509x306.png)
### 解决方案
1. 互斥锁:(基本不用次方案)
如果从redis中没有获取到数据,就让一个线程去数据库查询数据,然后构建缓存,其他的线程就等着,过一段时间后再从redis中去获取。
这个方案能解决问题,但是一个线程构建缓存的时候,另外的线程都在睡眠或者轮询。
2. 后台续命:
后台开一个定时任务,专门主动更新即将过期的数据。
设置 key 的时候同时设置过期时间为 60 分钟,后台程序在 55 分钟时,会查询数据库并重新缓存60分钟
3. 永不过期
对热点数据不设置过期时间
## 缓存穿透
要访问的数据缓存中没有,再查询数据库,还是没有。短时间,高密度的访问此数据,给持久层数据库造成很大的压力。
:-: ![缓存击穿](https://img.kancloud.cn/29/d4/29d4806090c935800acacf31886ff561_531x324.png)
### 解决方案
1. 缓存空对象
在数据库即使查到的是空对象,也把空对象缓存起来。
如果在某个时间,缓存为空的记录,在数据库里面有值了,怎么办?
1. 设置缓存的时候,同时设置一个过期时间,这样过期之后,就会重新去数据库查询最新的数据并缓存起来
2. 如果对实时性要求非常高的话,那就写数据库的时候,同时写缓存。这样可以保障实时性
3. 如果对实时性要求不是那么高,那就写数据库的时候给消息队列发一条数据,让消息队列再通知处理缓存的逻辑去数据库取出最新的数据
> 对于恶意攻击,请求的时候key往往各不相同,且只请求一次,那你要把这些key都缓存起来的话,因为每个key都只请求一次,那还是每次都会请求数据库,怎么办?—— 布隆过滤器
2. 布隆过滤器
当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在。
利用布隆过滤器先进行校验,不符合则
丢弃
:-: ![布隆过滤器](https://img.kancloud.cn/18/5c/185c85448d060d2e97dc5a390e22a189_679x321.png)
## 缓存雪崩
缓存中大多数的数据在**同一时间过期**,而查询数据量巨大,这时候,又是缓存中没有,数据库中有的情况了。请求都打到数据库上,引起数据库流量激增,压力瞬间增大,直接崩溃。
### 解决方案
1. 互斥锁
2. 错峰过期
在设置 key 过期时间的时候,加入一个随机过期时间,可以避免大量缓存同时过期
3. 缓存集群
4. 限流器+本地缓存
- PHP
- PHP 核心架构
- PHP 生命周期
- PHP-FPM 详解
- PHP-FPM 配置优化
- PHP 命名空间和自动加载
- PHP 运行模式
- PHP 的 Buffer(缓冲区)
- php.ini 配置文件参数优化
- 常见面试题
- 常用函数
- 几种排序算法
- PHP - 框架
- Laravel
- Laravel 生命周期
- ThinkPHP
- MySQL
- 常见问题
- MySQL 索引
- 事务
- 锁机制
- Explain 使用分析
- MySQL 高性能优化规范
- UNION 与 UNION ALL
- MySQL报错:sql_mode=only_full_group_by
- MySQL 默认的 sql_mode 详解
- 正则表达式
- Redis
- Redis 知识
- 持久化
- 主从复制、哨兵、集群
- Redis 缓存击穿、穿透、雪崩
- Redis 分布式锁
- RedisBloom
- 网络
- 计算机网络模型
- TCP
- UDP
- HTTP
- HTTPS
- WebSocket
- 常见几种网络攻击方式
- Nginx
- 状态码
- 配置文件
- Nginx 代理+负载均衡
- Nginx 缓存
- Nginx 优化
- Nginx 配置 SSL 证书
- Linux
- 常用命令
- Vim 常用操作命令
- Supervisor 进程管理
- CentOS与Ubuntu系统区别
- Java
- 消息队列
- 运维
- RAID 磁盘阵列
- 逻辑分区管理 LVM
- 业务
- 标准通信接口设计
- 业务逻辑开发套路的三板斧
- 微信小程序登录流程
- 7种Web实时消息推送方案
- 用户签到
- 用户注册-短信验证码
- SQLServer 删除同一天用户重复签到
- 软件研发完整流程
- 前端
- Redux
- 其他
- 百度云盘大文件下载
- 日常报错记录
- GIT
- SSL certificate problem: unable to get local issuer certificate
- NPM
- reason: connect ECONNREFUSED 127.0.0.1:31181
- SVN
- SVN客户端无法连接SVN服务器,主机积极拒绝
- Python
- 基础
- pyecharts图表
- 对象
- 数据库
- PySpark
- 多线程
- 正则
- Hadoop
- 概述
- HDFS