事故の概要のハイライト-Redisのキャッシュされたビッグキーによって引き起こされた事故-WangWenWen Qi 09(週に1回更新)

一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加した初日です。

【問題点の説明】

  • オンラインビジネスインターフェイスサービスはすぐにタイムアウトとアラームを開始し、アップストリームの発信者ポートの可用性率は80%に低下しました。

【事故レベル】

  • P0

【処理する】

  • 19:44アラームを受信し、インターフェイスtp99が300msを超えました(通常の状況では8ms)
  • 19:50マシンの監視を確認し、一部のマシンがタイムアウトし、問題のあるマシンがランダムに修正されていないことを確認します。
  • 19:55このインターフェースはキャッシュに依存し、ダウングレードスイッチがあり、dbをクエリします(スイッチがオフになっていることを確認してください)
  • 19:58キャッシュクラスターの監視を確認したところ、全体的にキャッシュクライアントの問題は見つかりませんでした
  • 20:03クラスターを表示して、キャッシュサーバーに問題がないことを確認するための運用および保守の支援
  • 20:10キャッシュされたコピーをスキャンし、1つの大きなキーが5Mを超えていることを確認し、引き続き要求します
  • 20:13大きなキーを削除し、クラスターを復元します

【失敗の原因】キャッシュビッグキーの問題!

要約:

高い同時トラフィックの継続的な影響により、さまざまな分散フレームワークと分散キャッシュが主要なインターネット企業の一般的なテクノロジースタックになりました。その中で、分散キャッシュテクノロジースタックとしてのredisキャッシュは、高い同時頻度の要求に高速に応答しています。応答はキャッシングで最高になります。

いつものインタビューでは、キャッシュキーの扱い方をよく聞かれます。次に、漢方薬の知識を活かして、キャッシュキーの見つけ方を分析します。キャッシュキーを判断する場合は、キャッシュキーの解決方法を説明します。 。

見る

インターフェイスサービスで、サービスが配置されているクライアントがキャッシュクラスターにのみ接続されている場合、インジケーターに基づいて、それがキャッシュキーの問題であるかどうかをすばやく確認するにはどうすればよいですか?

まず、redisサーバークラスターのハードウェアの問題を解消します。
まず、クラスターインジケーターを使用して、応答がタイムアウトする原因となるキャッシュサーバーマシンに異常があるかどうかを判断し、redisサーバーマシン、cpu、メモリのインジケーターを観察します。 、ネットワークなど、redisサーバーを除外します。ハードウェアの問題。

匂い

次に、クライアント接続のタイムアウトが中断される現象と、クライアントサーバーとredisサービス接続が中断される理由を確認します。

外観1:Redisシャードの着信トラフィックは大きくありませんが、発信トラフィックは膨大です

外観2:指定されたredisシャードがそれに応じてタイムアウトするたびに、発信トラフィックは膨大になりますが、他のシャードの発信トラフィックは正常です。

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

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

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

wecom-temp-f8602ac170a9b975b230e25fb3866c45.png

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

image.png

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

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

1、redis-rdb-tools工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析,找到其中的大KEY。 关于rdb工具的详细介绍请查看链接github.com/sripathikri… 基本命令:rdb -c memory dump.rdb (dump.rdb为Redis实例的rdb文件,可通过bgsave生成)

2、redis-cli --bigkeys命令。可以找到某个实例5种数据类型(String、hash、list、set、zset)的最大key。

3、自定义的扫描脚本,以Python脚本居多,方法与redis-cli --bigkeys类似。

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

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

1、redis本身定位就是一个内存缓存,而不是一个数据库,所以我们如果涉及到复杂的数据结构,建议设计之初就应该进行拆分。

2、在所有set缓存方法前,增加切面校验,设定阈值,校验存储的缓存key-value的大小,如果超过的话,阻止录入并且计入报警。

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

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

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

image.png

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负载均衡策略,默认是随机请求。

おすすめ

転載: juejin.im/post/7084904769579384863