閱讀642 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Redis故障案例(一)-特定key批量丟失

TroubleShooting-排障是DBA一項重要技能,通過故障表現的症狀,先讓業務快速恢複止損,同時分析故障的根因(rootCause),給出解決方案並從根本上修複故障,最後總結從產品或流程上怎麼規避同類型故障再次發生。

DBA排障很像醫生治病、刑警破案。

醫生通過了解病人病情症狀(故障症狀),先讓病人病情緩解(服務止損)類似止痛,同時分析病灶(故障根因),給出可行的治療方案(故障解決方案),病人完全恢複;最後給出醫療建議如何預防病情或避免惡化(故障規避);當然還有現多的類似急救(緊急故障-7位數級損失)、會診、不治、AI醫療(AI故障根因分析)、醫療事故(背鍋);其實很多相通之處。

刑警通過真凶(故障根因)留下的犯罪現場(故障症狀),根據羅卡定律,各種技術分析和尋找證據,最終找出真凶和證據。(段子很多,先回到主題)

在Redis早期的運維過程中,也遇過不少Redis故障,現總結其中幾個有意思的案例,希望對剛開始用Redis的DBA同學有所幫助。故障因與業務、故障場景結合較密切(脫敏),筆者盡量提煉成技術和還原現場;故障係列文章包括以下幾部分:

故障背景:主要交待技術和故障背景[可選];

故障描述:故障的簡單描述、根本原因和影響;

故障監控告警:故障相關的監控告警信息;

故障分析:文章核心 提供類似故障的分析思路、和技術點;

故障階段性總結:文章核心 總結類似故障的通用性預防;

本文是Redis故障案例(一)關於一次Redis特定key丟失排查分析。

1 故障背景

A業務有一個3分片的Redis Cluster緩存集群,會定期生成數據寫入Redis; 某一天,A業務的研發工程師(下文簡稱RD)突然找到DBA,很激動地說:“我們Redis集群突然掉很多key…” ,然後故事就開始了….

RD: “我們Redis集群中,以“t_list:”前綴的90000多key今早發現都掉了,其他key還在,是不是DBA有清理操作啊?”
DBA: “沒有維護性操作(一臉懵B和無辜),先止損,把Key從Primary store中導入Redis;”
RD: “已經從MySQL把key導入到Redis,現在業務功能恢複,影響很小。但請幫忙追查原因。“

DBA: “這部分key確認最近一次還在是什麼時候? 然後最早發現丟失是在什麼時候?” 備注:DBA開始和當事人了解案發時間,為排查問題提供依據。
RD: “昨晚20:30前key肯定還在,最早發現key不見是今早9:20同事發現新測試功能有異常” 備注:灰度功能
DBA: ”好的,我先分析一下原因,有結果了通知你;定位問題前,你也關注一下服務,避免問題二次發生”。

然後RD就下樓了,DBA扣上他的幾十元買來的boss耳機,開始自言自語Troubleshooting.

2 故障描述

因RD1同學為重寫t_list的90000多個KEY, 通過keys t_list*命令獲取並刪除,但未及時把key新內容重到redis中;使得RD2同學以為數據靈異丟失。但因為是灰度功能使用數據,服務影響範圍較小。

3 故障告警

1 業務告警缺失;見故障總結
2 Redis側無法監控此類告警

4 故障分析

通過RD提供的線索:

  • 特定t_list:前綴90000個List元素丟失;
  • 數據丟失時間範圍前日20:30~9:20之間(案發時間段,分析各種監控範圍)。

通過故障症狀初步分析,故障可能的根因:

  • 行了flushall/flushdb命令刪除所有key,其他key是後來寫入的,造成了隻丟失t_list的假象
  • 這90000個List元素因執行LPOP/RPOP,導致key被刪除的現象;(List中元素被全部pop完後,list相當於被刪除了)
  • 這部分key因設置了TTL,在此期間內全部過期,被redis自動刪除;
  • 這部分key因LRU淘汰,被redis全部驅逐淘汰;
  • 程序BUG或人為刪除導致;

每個可能故障根因排查分析:

  • 排除flushall/flushdb導致;因此集群兩個命令是被rename了,同時觀察集群監控dbsize為了跌為0的區段; info Commandstats中沒cmdstat_flushdb、cmdstat_flushall輸出都可確認,不是flush造成的。
  • 排隊List pop操作導致的;通過分析案發時間段內的監控圖,並未發現cmdstat_rpop和cmdstat_lpop輸出;
  • 排除過期刪除導致; 分析監控,最近24小時expired_keys監控指標值基本為0
  • 排除LRU淘汰導致;本集群實例未設置淘汰,maxmemory-policy為noeviction;分析監控,最近24小時evicted_keys監控指標值都是0。
  • 確認是程序BUG或人為刪除導致;最後定位是RD1同學,為重寫這部分key,通過腳本keys t_list:*獲取,並通過del命令刪除。詳細分析過程如下:

通過分析redis監控單個分片key個數,發現22:00到22:40時間段內,key個數下降約30000個;此集群共3個數據分片,且每個分片slots分配均勻,三個分片同時段key個數下降約90000個;和故障丟失key個數相符。

f24dff31419880efe03ce0e1405ca115f5658caf

圖1. 數據key個數監控圖


再分析DEL的操作,22:00~22:40時間段內,每個Redis的每秒del操作12次,持續40min; 約30000個del操作; 3個分片,共執行約90000次DEL操作

ead69d0f61d243eaa0a1d43239a594ff0a77eaa6

圖2. 刪除操作DEL的每秒請求數監控圖


查看slowlog監控,2015-12-03 22:01:01 時間點,執行KEYS “tlist*” 獲取所有key的前綴, 目的應該是執行後麵的DEL操作

56326f61b960efebeef41d1237526c4a0efe212e

圖3. slowlog分析圖

5 故障階段性總結和預防

  • 禁用keys命令(程序曆史原因),DBA提供刪除特定key的自助化服務;盡量避免RD直接操作Redis集群數據,通過review的流程減少誤操作的發生;
  • 業務方加強監控告警,業務異常能及時發現。

非技術類總結:

  • 數據是公司重要的資產和生命線,DBA除了本職工作做好數據的安全和可靠外;實際工作也有很多類似的“數據丟失”場景,怎麼從技術層麵不做背鍋俠;
  • 做好完善的監控,是精細化運營管理和自我保護的前提。


原文發布時間為:2017-11-20

本文作者:RogerZhuo

本文來自雲棲社區合作夥伴“老葉茶館”,了解相關信息可以關注“老葉茶館”微信公眾號

最後更新:2017-11-23 00:34:08

  上一篇:go  大數據人工智能領域從菜鳥到高手晉級指南
  下一篇:go  高並發IM係統架構優化實踐