考虑一个简单的场景,只有MySQL数据库和Redis在存放数据,然后用户发起查询请求,然后又下面几个问题。
缓存穿透/击穿
- 缓存穿透: 用户请求的数据在redis缓存里头和MySQL都没有,当大量用户并发请求,MySQL压力过大,容易奔溃。
- 缓存击穿:redis缓存里头某个热点key失效时,大量用户并发请求直接来到MySQL数据库上,MySQL压力过大,容易奔溃。
缓存雪崩
当redis缓存中大部分key在某个时间内集体失效了(或者redis宕机了),大量用户并发请求直接来到MySQL数据库上,MySQL压力过大,容易奔溃。
解决方案
通用解决方案
- 接口增加用户鉴权,一些热点接口甚至需要考虑一下是否需要设置同个用户某段时间内的访问次数。
缓存穿透解决方案
- 缓存和数据库中都没有取到数据后,可以将key-value对写为key-null,注意控制好缓存时间,太长可能影响业务的正常进行。
- 增加布隆过滤器,通过数据预热将可能涉及到的数据以hash方式进行存储,这样可以过滤部分无效请求。
缓存击穿解决方案
- 根据其含义,可以考虑设置热点数据永远不过期。
- 加互斥锁。
缓存雪崩解决方案
- 暴力的解决方法,设置所有key不过期(注意内存使用情况)
- 随机化缓存数据的过期时间
- 如果redis进行集群部署,尽量将数据均匀分布(考虑一致性hash算法)