Redis—缓存雪崩、击穿、穿透问题与解决

Redis雪崩

商城首页以及热点数据都会做缓存
一般缓存都是定时任务去刷新,或者是查不到之后去更新
定时任务刷新就有一个问题
例:
如果所有首页的key的失效时间都是12小时,中午12点刷新
零点有个秒杀活动大量用户涌入,假设每秒6000个请求,本来缓存在可以扛住每秒5000个请求,但是缓存当时所以的key都失效了。
此时1秒6000个请求全部在数据库,数据库必然扛不住,DBA(数据库管理员)都没反应就直接挂了。
此时数据库重启数据库又被新的流量打死。这就是缓存雪崩。
流程图
同一时间大面积失效,那一瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想想如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,并且对你的产品失去了信心,什么垃圾产品。

解决:
1、批量存Redis数据的时候,每个key的失效时间都加上随机值,确保数据不会在同一时间大面积失效。
2、Redis集群部署,将热点数据均分在不同的Redis库中
3、设置热点数据永远不过期,有更新操作就更新缓存(例如首页更新商品,直接更新缓存,不设置过期时间)电商首页数据也可以,保险。

Redis缓存穿透

缓存穿透是指缓存和数据库中没有的数据,而用户不断发起请求,我们数据库的id都是1开始自增上去的,如发起id值为-1的数据或id特别大不存在的数据。这时候的用户很有可能是攻击者,导致数据库压力过大,严重会击垮数据库。
穿透
如果不做参数校验,数据库id都是大于0的,我一直用小于0的参数去请求你,每次都能绕开redis直接打到数据库,数据库也查不到,并发高点就容易崩掉了。

解决:
在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等。
Redis的高级用法**布隆过滤器(Bloom Filter)**这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在就return,存在你就去查DB刷新KV再return。

Redis缓存击穿

和缓存雪崩有点像但又不一样,缓存雪崩是大面积缓存失效,打崩了DB,而缓存击穿是指一个key非常热点,在不停但扛着大并发,大并发集中对这一个点进行访问,当这个key在失效瞬间,持续的大并发就穿破缓存,直接请求数据库。

解决:
从缓存取不到数据,在数据库也取不到,这时也可以将对应的key的value写为null、位置错误、稍后重试这样的值取啥看具体场景问产品,缓存有效时间可以设置短点,差不多30s(太长会导致正常情况也没办法使用)。
这样可以防止攻击用户反复用同一个id反复id暴力攻击,但是我们要知道正常用户是不会在单秒内发起那么多次请求的,那网关层Nginx有配置,单个IP每秒访问次数超出阀值的IP都拉黑。
如果黑客用多个IP同时发起进攻呢,正常级别的Redis集群都能扛住这种级别的访问,小公司他们不会感兴趣的,把系统的高可用做好了,集群还是很顶的。
设置热点数据永远不过期。或者加上互斥锁就能搞定

预防

  • 事前:Redis高可用,主从 + 哨兵,Redis cluster,避免全盘崩溃。
  • 事中:本地ehcache缓存 + Hydtrix限流 + 降级,避免Mysql被打死。
  • 事后:Redis持久化 RDB + AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?
走降级!可以返回一些默认值、友情提示、或者空白值。
优点:数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。只要数据库不死,就是说,对于用户来说,3/5的请求都是可以被处理的,就说明系统没死,用户可能就是点击刷几次就可以刷出来。

你是不是好奇,某明星爆出什么事情,你发现你去微博怎么刷都空白界面,但是有的人又直接进了,你多刷几次也出来了,现在知道了吧,那是做了降级,牺牲部分用户的体验换来服务器的安全,可还行?

ps:
开发程序的时候都要有一颗”不信任“的心,就是不要相信任何调用方。比如你接口是分页查询的,但是你没有对分页参数大小做限制,调用的人请求你个最大值,一次请求你几秒,多几个并发你就挂了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值