# Redis高并发常见3大问题


![image](/images/redis_00.png)

## 缓存穿透
&emsp;&emsp;他是指大量请求访问的数据，在缓存和数据库中均不存在，导致请求直接穿透缓存层，频繁访问数据库，造成数据库压力过大，响应过慢，甚至宕机。其原因可能是黑客构造大量不存在的key发送请求，或者业务代码逻辑`bug`，查询了大量`key`不存在或者无效数据。  
### 解决方案
- 在数据查询不到数据时，向`redis`缓存一个空值，并设置一个较短的过期时间(比如`5`分钟)，这样下次请求相同的`key`时就能命中缓存，将空值返回给客户端。
- 使用布隆过滤器对所有的key进行预判，对于不存在的`key`，直接返回或拒绝请求，只有存在的`key`才会去查询缓存
- 对请求参数进行校验，过滤掉明显无效的请求，如ID格式必须合法等，只有合法的`ID`才会去查询缓存

## 缓存击穿
&emsp;&emsp;他是指某个热点数据在缓存中过期，导致大量请求同时访问数据库，造成数据库瞬间压力过大，甚至服务不可用
### 解决方案
- 对于核心热点数据，可以设置永不过期，或者使用定时任务定期更新缓存，确保热点数据可以命中缓存
- 在缓存失效时，使用分布式锁(如`redis`的`setnx`)保证只有一个请求去查询数据库，其他请求等待，该请求查询到数据库后在更新到缓存中，这样后续请求就又能命中缓存了 

## 缓存雪崩
&emsp;&emsp;他是指大量缓存数据在同一时间点过期，导致大量请求直接访问数据库，造成数据库崩溃，可能的原因是设置了相同的过期时间，或者redis服务器宕机或者重启
### 解决方案
- 设置不同的过期时间，避免大量数据同时过期
- 缓存预热，在系统启动时，提前将热点数据加载到缓存中
- 熔断降级，使用熔断器(如`Hystrix`)对请求进行限流，限制数据库访问量，当数据库压力过大时候，直接返回默认值或错误提示

---

> 作者: [0x5c0f](https://blog.0x5c0f.cc)  
> URL: https://blog.0x5c0f.cc/posts/linux/redis%E9%AB%98%E5%B9%B6%E5%8F%91%E5%B8%B8%E8%A7%813%E5%A4%A7%E9%97%AE%E9%A2%98/  

