缓存穿透
用户查询数据,若redis内存数据库没有(未命中),就会向持久化数据库查询,也没有,则此次查询失败。当存在大量用户去请求这些redis内存数据库中没有的数据时,就都去请求了持久层数据库,会给持久层数据库造成较大压力,这种现象叫缓存穿透。
解决方法:
- 持久层数据库:当存储层未命中,即使缓存空对象也将其缓存起来,同时设置过期时间,之后再访问此数据就会从redis内存数据库中获取,从而减轻持久层数据库的压力。
- 布隆过滤器:布隆过滤器为一种数据结构,对所有可能查阅的参数以Hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。
缓存击穿
缓存击穿是指一个key非常热点,大并发集中对这一个点进行访问,当这个热点非常大的key实效的一瞬间,持续的大并发就击穿缓存,直接请求持久层数据库,会导致数据库压力过大。
解决方法
- 设置热点数据永不过期
缓存雪崩
缓存雪崩是指在一段时间内缓存集中过期实效。例如双十一零点抢购,有一波商品被购买,那么它们时间比较集中的放入了缓存,假设只缓存了半小时,半小时之后到期实效,那么顾客对这批商品的访问查询就落到了数据库上,对数据库而言就会产生周期性的压力,会造成存储层也挂掉的情况。
解决方法
- 限流降级:在缓存实效后,通过加锁或队列来控制读数据库写缓存的线程数量(比如对某个key只允许一个线程查询数据和写缓存,其他线程等待)
- redis高可用:既然redis有可能挂掉,那么多增设几台redis,这样一台挂掉之后其他redis还可以继续工作,也就是搭建集群。
- 数据预热:在正式部署之前,先把可能的数据预先访问一遍,这样大部分可能大量访问的数据就会加载到缓存中,在即将发生大并发访问前先手动触发加载缓存不同的key、设置不同的过期时间,让缓存实效的时间点尽量均匀(不集中)。