Redis的缓存问题
缓存雪崩
数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。
解决方案:
- 缓存的过期时间多增加一个随机的时间, 让key随机失效
- 定时任务, 定期刷新缓存
缓存穿透
缓存穿透是指查询一个一不存在的数据。例如:从缓存redis没有命中,需要从mysql数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决方案:
- 参数校验
- 在第一次获取缓存后, 如果没有查询出来, 设置一个标记key; 第二次查询时, 查询标记key并且返回
- 如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,一般只有几分钟。
- 布隆过滤器, 将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
- 对恶意发起请求的ip过滤
缓存击穿;缓存并发
在秒杀等场景中, 某一热点key突然失效, 此时大量并发请求打到数据库上, 把数据库压垮
解决方案:
- 对缓存查询加锁, 单体应用下使用互斥锁, 分布式使用分布式锁