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