Redis:缓存雪崩、击穿、穿透

雪崩(key都过期了)

  1. 现象:redis若采用定时刷新(redis),某时刻秒杀的时候可能redis里所有的key都失效了,都会大量请求去请求数据库,而数据库马上就挂了,重启之后又被新的流量打死了。
  2. 解决
    2.1. 把每个key的失效时间设置一个随机值,可以保证数据不会在同一时间大面积失效。
    2.2. 或者设置热点数据永不过期,有更新操作就更新缓存就好了(比如更新了首页商品,刷下缓存就行了(但定期主动删除是随机的吧),可以写个脚本将新的商品新点一下,这样内存就会淘汰那些很老的)

击穿(大量被访问热点key突然过期)

  1. 现象:缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。
  2. 解决
    2.1 设置热点数据永不过期。
    2.2 给访问redis不存在->访问mysql->写入redis 这一整个过程加上锁,就会保证key在一次失效之后,写入redis过程中不会大量都来访问数据库。可以让线程超时等待锁,等不到的话再访问下redis说不定这个key的数据再redis已经又存在了。

穿透(key在redis/db都不存在)

  1. 现象:缓存和数据库中都没有的数据,用户不断发起请求,比如发起id=-1的数据的查询,这时候用户很可能很可能是黑客。这样就会大量会查找数据库,就又挂了,正常情况下数据库找不到是不会放入redis中的。
  2. 解决
    2.1. 对参数进行合法校验,和对用户进行校验,假如一个ip在单位时间发起了大量请求就拉黑他。
    2.2 在数据库没有取到的话,将对应的key的value写为null,写到redis中,不过要将这样的key的过期时间设置短一点,毕竟黑客只是极少数的,假如redis里全是不合法的key,这不也是会造成雪崩。。
    2.3 Redis还有一个高级用法布隆过滤器(Bloom Filter)这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在Redis中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。

总结

  • 事前:Redis高可用,主从+哨兵,Redis cluster,避免全盘崩溃
  • 事中:本地ehcache缓存+Hystrix限流+降级,避免Mysql挂掉。
  • 事后:Redis持久化 RDB+AOF,一旦重启后,快速恢复Redis数据。

解释一下限流和降级:限流组件确保了每秒只有多少个请求能通过。 只要数据库不死,就是说,对用户来说,3/5 的请求都是可以被处理的。 只要有 3/5 的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。这个在目前主流的互联网大厂里面是最常见的,你是不是好奇,某明星爆出什么事情,你发现你去微博怎么刷都空白界面,但是有的人又直接进了,你多刷几次也出来了,现在知道了吧,那是做了降级,牺牲部分用户的体验换来服务器的安全。

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/109357306