Redis数据“丢失”问题
from:?https://zhuoroger.github.io/2016/08/14/redis-data-loss/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io?ref=myread
Redis數據“丟失”問題
?2016-08-14?? | ???Redis?? | ??17條評論?? | ???2190Redis大部分應用場景是純緩存服務,請求后端有Primary Storage的組件,如MySQL,HBase;請求Redis的鍵未命中,會從primary Storage中獲取數據返回,同時更新Redis緩存。
如果少量數據丟失,相當于請求”緩沖未命中“; 一般對業務的影響是無感知的。
但現在Redis用作存儲的業務場景變多,數據丟失對業務是致命的影響。
本文簡單討論Redis常見數據”丟失“現象,以及怎么規避;會列舉幾個生產中有意思的情節。
記1次Redis”數據丟失“的故障排查
Redis數據被丟失問題,發生次數也很多; 如何快速定位問題和避免呢。
先分享一個小故事(大家都喜歡帶情節的片,不對是技術文章)
情節:我的Redis掉了90000多個Keys, 是不是DBA有刪除操作?
(時間:12-04日;故事人物:RD(研發工程師)和DBA; 故事:Redis一夜之間不見90000個key)
RD:我們Redis集群中,以“t_list”前綴的90000多key今早發現都掉了,其他key都在,是不是DBA有清理操作啊?
DBA:沒有維護性操作(一臉懵B和無辜),先止損,把Key從Primary store中導入Redis;我先分析一下原因,有結果了通知你;定位問題前,你也關注一下,避免二次發生。
RD:“已從MySQL把key導入到Redis. 好的,等你消息。”
然后RD就下樓了,DBA扣上他的25元的boss耳機,開始自言自語Troubleshooting.
“這部分key未設置TTL, 查看監控的 expired_keys基本都是0”
“是否達到了maxmeory,key被強制驅逐淘汰了? 查看監控 used_memory_pct未到100%,查看 evicted_keys一直為0,最近24小時無key被淘汰”
“只是部分key丟失,而且都是同一個key前綴,說明這個兇手很了解業務;查看監控的實例總key數, keys指標,發現果斷keys果斷下降,但未變為0,排除Flushall/flushdb和Redis, 定位是程序或人為操作”
“如果程序主動刪除key, 就只能是DEL操作,查看監控comdstat_del指標,表示每秒執行的Del次數,果然平時基本為0,昨晚22:01開始有每秒幾十個的del”
“再查看slowlog, 22:01時,執行 ‘ KEYS tlist*’ 的命令,獲取這類key,進行批量清理”
這時問題定位了, 一首歌多的時間。 然后DBA通知RD排查的結論,讓其他排查程序或人為操作;
分析證據簡述如下:
從03日的Redis key監控可見,22:00到22:40這個數據key個數下降30000(1個分片,此集群共3個分片)
03日22:00~22:40分之間,Redis的DEL操作大約12個,持續40min; 刪除126040約29000個key.(3個分片,共刪除約90000個key)
查看slowlog監控,2015-12-03 22:01:01 時間點,執行KEYS “tlist*” 獲取所有key的前綴, 目的應該是執行后面的DEL操作
說明:精細化的監控告警很重要。
數據丟失的影響
- Redis存儲的應用場景,數據丟失是不能接受的;
因為Redis的持久化特性,數據還原很難保證一致性,因rdb全備和aof重寫備份,RPO不能像MySQL這樣保證恢復到故障操作的前一個事務。 - 緩存的應用場景,如果大量緩存數據丟失,往往導致后端存儲組件”打死“,應用程序雪崩的情況
常見Redis數據丟失的情況
- 程序bug或人為誤操作
- 因客戶端緩沖區內存使用過大,導致大量鍵被LRU淘汰
- 主庫故障后自動重啟,可能導致數據丟失
- 網絡分區的問題,可能導致短時間的寫入數據丟失
- 主從復制數據不一致,發生故障切換后,出現數據丟失
- 大量過期鍵,同時被淘汰清理
程序bug或人為誤操作
如前文情節1,程序bug誤刪除數據; DBA/RD誤操作執行flushall/flushdb這類命令。
這類問題的預防和監控
1 重命名危險命令:keys(程度大批量誤刪除,很多通過keys獲取鍵后再刪除),flushall,flushdb
2 細化幾個重要的監控項:
- 實例當前的鍵個數(dbsize/info), 當大量鍵丟失時,可通過此項歷史監控圖,定位發生的時間范圍
- 各類刪除命令的執行數監控:cmdtats_flushall, cmdstats_flushdb,cmdstat_del
對應時間范圍,確認具體是什么操作
因客戶端緩沖區內存使用過大,導致大量鍵被LRU淘汰
因客戶端緩沖區的內存大小很難限制,它們消耗的內存數會計算在used_memory內;如果使用不當,
導致緩沖區內存使用過大,達到maxmemory限制;(緩存場景)會導致大量的鍵被淘汰,最壞會把所有鍵清理,緩沖無鍵可淘汰,寫入失敗。相當于整個緩沖失效,對業務影響較大。
關于Redis客戶端緩沖區問題,詳細分析見之前文章Redis Clients Two Buffers
這類問題的預防和監控:
1 業務容量規劃時把緩沖正常消耗計算在內,合理高大maxmemory的限制;
每個實例最好可預留幾百M(大小根據客戶端連接數和key的使用有關,根據大小集群合理調整)
2 對輸出緩沖區設置合理limit;如normal設置10MB, SLAVE設置1GB等。 如果復制因slave線程輸出緩沖區反復同步,需臨時調大slave client-output-buffer,要同時調大maxmemory限制。
說明:關于Redis復制中斷和無限同步,詳細分析請見Redis復制中斷和無限同步問題
3 主要監控
- 監控內存使用大小 used_memory
- 監控兩個buffer的使用量client_longest_output_list和client_biggest_input_buf
- 監控鍵的LRU驅逐數量:evicted_keys
主庫故障后自動重啟,可能導致數據全部丟失
這種故障發生,極有可能數據全部丟失。
問題發生的現象:時間點T1,主庫故障關閉了,因設置有自動重啟的守護程序,時間點T2主庫被重新拉起,因(T2-T1)時間間隔過小,未達到Redis集群或哨兵的主從切換判斷時長;這樣從庫發現主庫runid變了或斷開過,會全量同步主庫rdb清理,并清理自己的數據。
而為保障性能,Redis主庫往往不做數據持久化設置,那么時間點T2啟動的主庫,很有可能是個空實例(或很久前的rdb文件)。
這種問題發生時間間隔,一般小于1分鐘,可能監控告警無法感知到。
這類總是的預防和監控:
1 強烈反對Redis粗暴地設置自動重啟
2 這種監控鍵個數的變化,緩存命中率,同時ELK類型準實時監控redis日志變化并告警
建議:數據庫這類重“狀態性”服務,不建議程序暴力自動重啟
網絡分區的問題,可能導致短時間的寫入數據丟失
這種問題出現丟失數據都很少,網絡分區時,Redis集群或哨兵在判斷故障切換的時間窗口,這段時間寫入到原主庫的數據,5秒~15秒的寫入量。
詳細分析參考:
Reply to Aphyr attack to Sentinel
redis-sentinel-at-flickr
圖片(引至參考2): Redis哨兵結構的網絡分區導致的“split-brain”場景
主從復制數據不一致,發生故障切換后,出現數據丟失
主從數據出現不一致,發生故障切換,從庫提升為主后,導致數據丟失的情況。
關于Redis復制數據不一致,請參考Redis復制主從數據不-致
大量過期鍵,同時被淘汰清理
這類情況不是真正的“數據丟失”,只是定期主動清理Redis堆積的過期鍵,會導致Redis的鍵個數(dbsize)出現陡降(最大能達20%)。業務方常誤以為有數據丟失。
這時可通過監控過期鍵淘汰的數量:expireed_keys的增長量,與dbsize鍵總數減少數據量是否相等。
說明:關于過期鍵,大量堆積成為“死鍵”問題,詳細分析參考Redis的“死鍵”問題
歡迎大家留言補充,遇到的數據丟失場景。
#Redis ?Redis復制主從數據不-致 ? 細說Redis監控和告警(待完善)?- 17條評論?
- 1條新浪微博
- 黃華亮
Mac OS 10.11.2
Chrome 52.0.2743.116深入透徹,推薦學習~ 使勁打RD,這黑鍋太大了啊?
8月16日回復頂轉發 - 代碼館
Windows 7
Chrome 52.0.2743.116請問, 然后DBA通知RD排查的結論,讓其他排查程序或人為操作;這結論啥意思。
8月17日回復頂轉發 - 劉sir
Windows 7
Firefox 48.0怒贊!
8月17日回復頂轉發 - bigger-uncle
Windows 7
Chrome 49.0.2623.110看來redis有個系列
8月17日回復頂轉發 - 今天今天
Mac OS 10.11.6
Chrome 52.0.2743.116回復 代碼館:?通過排查定位是程序或工程師刪除的。就通過到業務方,讓其組內定位同時段的問題。
8月17日回復頂轉發
這個例子主要為了說明:數據丟失的一些排查思路。 - 今天今天
Mac OS 10.11.6
Chrome 52.0.2743.116回復 bigger-uncle:?可以寫一個系列。大家有感興趣的,可以列舉出來。
8月17日回復頂轉發 - 今天今天
Mac OS 10.11.6
Chrome 52.0.2743.116回復 黃華亮:?
8月17日回復頂轉發 - 小城
Windows 7
Chrome 52.0.2743.116樓主是用的什么監控工具呢?
8月17日回復頂轉發 - 今天今天
Mac OS 10.11.6
Chrome 52.0.2743.116回復 小城:?公司監控平臺是Falcon,自己寫的Redis監控插件:https://github.com/ZhuoRoger/redismon
8月17日回復頂轉發 - phperstar
Windows 7
Chrome 42.0.2311.154好文...
8月17日回復頂轉發 - 小易分享網
Windows 7
IE 9.0今天才發現你的博客,連著看了幾篇呢 http://www.xevip.cn
8月18日回復頂轉發 - 神韻夜殤
Windows 10
Chrome 50.0.2661.102學習了 某米的DBA啊 哈哈~
8月18日回復頂轉發 - Vim0x3c
Windows 7
Chrome 51.0.2704.103哈哈哈哈哈哈 強行甩鍋
8月18日回復頂轉發 - carlosfl
Windows 7
Chrome 48.0.2564.82問個題外話,hexo每篇文章的訪問量組件是用的什么?
8月20日回復頂轉發舉報 - 今天今天
Mac OS 10.11.6
Chrome 52.0.2743.116回復 carlosfl:?用的NexT主題自帶PV/UV設置。
8月21日回復頂轉發 - carlosfl
Windows 7
Chrome 38.0.2125.104回復 今天:?我也用的NextT..能麻煩說一下嗎 謝謝。
8月22日回復頂轉發 - 奇虎分享網
Windows 7
IE 9.0感謝分享 祝您開心快樂每一天!
8月23日回復頂轉發
總結
以上是生活随笔為你收集整理的Redis数据“丢失”问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 缓存架构设计细节二三事
- 下一篇: 终于找到程序员无休止加班的原因了