快捷搜索:  汽车  科技

如何解决redis缓存雪崩击穿与穿透(专治Redis缓存大key引起的事故)

如何解决redis缓存雪崩击穿与穿透(专治Redis缓存大key引起的事故)接下来找下客户端连接超时中断的现象,以及为什么客户端服务器会和redis服务连接中断。闻望在一个接口服务里,如果我们的服务所在的客户端,只连接了缓存集群,我们如何快速的根据指标确认是否是缓存大key问题。首先排除Redis服务端集群硬件问题。我们先通过集群指标,判断是否有缓存服务端机器异常,引起的响应超时,观察redis服务端机器的各项指标,cpu、内存、网络等,排除redis服务端硬件的问题。

问题描述

线上业务接口服务瞬间开始超时报警,上游调用方端口可用率下降至80%,属于P0级别事故,具体过程如下:

  • 19:44 接到报警,接口tp99超过300ms(正常情况下8ms);
  • 19:50 查看机器监控发现部分机器超时,问题机器随机不固定;
  • 19:55 此接口依赖缓存,有降级开关,查询db(确认开关关闭);
  • 19:58 查看缓存集群监控,整体未发现缓存客户端问题;
  • 20:03 运维协助查看集群,确认缓存服务端没有问题;
  • 20:10 扫描缓存副本 发现有单个大key超过5M,并且持续请求;
  • 20:13 删除大key,集群恢复 【故障原因】 缓存大key问题!

随着高并发流量的持续冲击,各种分布式框架、分布式缓存已经成为各大互联网公司的常用技术栈,其中就有redis缓存,作为一个分布式缓存技术栈,在应对高并发频次的请求,以及快速的响应成为缓存中的佼佼者。

我们在平时的面试中,也会经常被问到缓存大key如何处理的问题,接下来,我们借鉴中医学的望闻问切来分析如何发现缓存大key,如果判断缓存大key,如果解决缓存大key。

在一个接口服务里,如果我们的服务所在的客户端,只连接了缓存集群,我们如何快速的根据指标确认是否是缓存大key问题。

首先排除Redis服务端集群硬件问题。我们先通过集群指标,判断是否有缓存服务端机器异常,引起的响应超时,观察redis服务端机器的各项指标,cpu、内存、网络等,排除redis服务端硬件的问题。

接下来找下客户端连接超时中断的现象,以及为什么客户端服务器会和redis服务连接中断。

  • 表象1:redis分片入流量不大,出流量巨大。
  • 表象2:每次都是指定redis分片相应超时,出流量巨大;而其余分片出流量正常。

我们先要清楚一个知识点,就是缓存的数据路由,Redis Cluster采用虚拟哈希槽分区而非一致性hash算法,预先分配16384(2^14)个卡槽,所有的键根据哈希函数映射到 0 ~ 16383整数槽内,每一个分区内的master节点负责维护一部分槽以及槽所映射的键值数据。

所以我们存入redis的每一条数据,在分片不变的情况下,始终存储在一个分片上。我们根据这个特点,结合监控集群的指标反应,可以快速定位是否是缓存大key。

正常情况下出流量各个分片出流量监控:

如何解决redis缓存雪崩击穿与穿透(专治Redis缓存大key引起的事故)(1)

缓存大key导致的固定分片出流量大:

如何解决redis缓存雪崩击穿与穿透(专治Redis缓存大key引起的事故)(2)

这种基本就可以确定是缓存大key的问题了,我们继续下一步,如何快速找到这些缓存大key,并且删掉。

找到问题的缓存分片,针对缓存分片进行大key扫描,网上方法有很多,感兴趣的话可以自己搜索,在此只介绍集中比较热门的方式。建议公司运维同事提前搭好类似的基础服务工具。

  • redis-rdb-tools工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析,找到其中的大KEY。基本命令:rdb -c memory dump.rdb (dump.rdb为Redis实例的rdb文件,可通过bgsave生成)。
  • redis-cli --bigkeys命令。可以找到某个实例5种数据类型(String、hash、list、set、zset)的最大key。
  • 自定义的扫描脚本,以Python脚本居多,方法与redis-cli --bigkeys类似。

自此可以找出缓存的中的大key。执行 del 命令删除大key即可。

我们如何预防,才是重点。

  • redis本身定位就是一个内存缓存,而不是一个数据库,所以我们如果涉及到复杂的数据结构,建议设计之初就应该进行拆分。
  • 在所有set缓存方法前,增加切面校验,设定阈值,校验存储的缓存key-value的大小,如果超过的话,阻止录入并且计入报警。

最后我们解释下,为什么缓存大key会导致服务端链接缓存超时链接中断的现象。

先了解一个概念,redis缓冲区一共有三个,客户端缓冲区、复制及压缓冲区、AOF缓冲区,大key问题导致客户端-服务端链接中断的原因就在于第一个:客户端缓冲区。

Redis为每个客户端分配了输入缓冲区, 它的作用是将客户端发送的命令临时保存, 同时Redis从会输入缓冲区拉取命令并执行, 输入缓冲区为客户端发送命令到Redis 执行命令提供了缓冲功能, 如图所示。

如何解决redis缓存雪崩击穿与穿透(专治Redis缓存大key引起的事故)(3)

Redis 为每个客户端设置的输出缓冲区也包括两部分:一部分,是一个大小为 16KB 的固定缓冲空间,用来暂存 OK 响应和出错信息;另一部分,是一个可以动态增加的缓冲空间,用来暂存大小可变的响应结果。造成输出缓冲区溢出的原因:

  • 大key请求返回的结果
  • 执行了Monitor命令
  • 缓冲区设置大小不合理

限制输出缓冲区的配置:

  • client-output-buffer-limit normal 0 0 0 普通客户端不做限制,请求是阻塞式的。
  • client-output-buffer-limit pubsub 8mb 2mb 60 发布订阅式 总量8mb 60s内超过2mb就会自动关闭连接 。

避免溢出的方式显而易见:

  • 避免bigkey
  • 生产不使用Monitor操作
  • 合理设置client-output-buffer-limit

这也是我们的服务接口所在的客户端服务器,和redis服务端中断的根本原因,中断之后,客户端的检测狗会重新和redis服务端建立新的链接。

至于redis服务端为什么每次中断的客户端服务器链接都是随机的呢?答案就在于我们的dubbo负载均衡策略,默认是随机请求。

作者丨树洞君

来源丨网址:https://juejin.cn/post/7084904769579384863

dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn

更多精彩内容

为夯实数据和算法的“地基”,进一步推动智能运维(AIOps)的深入落地,今晚18:30,中国信息通信研究院云计算与大数据研究所联合dbaplus社群,携手来自微众银行、虎牙直播的AIOps专家,围绕“让数据与算法精准发力,突破智能运维发展困局”这一主题开展线上直播分享,针对《2022 中国AIOps现状调查报告》权威解读、数据智能检测、业务降本增效等内容进行深度探讨,为各行各业的智能运维能力建设提供更明确的参考路径。

复制链接到微信,可直接免费观看哦~

http://z-mz.cn/5qUCE

如何解决redis缓存雪崩击穿与穿透(专治Redis缓存大key引起的事故)(4)

关于我们

dbaplus社群是围绕Database、BigData、AIOps的企业级专业社群。资深大咖、技术干货,每天精品原创文章推送,每周线上技术分享,每月线下技术沙龙,每季度Gdevops&DAMS行业大会。

关注公众号【dbaplus社群】,获取更多原创技术文章和精选工具下载

猜您喜欢: