欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis主從切換導(dǎo)致的數(shù)據(jù)丟失與陷入只讀狀態(tài)故障解決方案

 更新時(shí)間:2023年05月22日 08:16:24   作者:及時(shí)  
這篇文章主要介紹了redis主從切換導(dǎo)致的數(shù)據(jù)丟失與陷入只讀狀態(tài)故障解決方案的相關(guān)資料,需要的朋友可以參考下

背景

最近一組業(yè)務(wù)redis數(shù)據(jù)不斷增長(zhǎng)需要擴(kuò)容內(nèi)存,而擴(kuò)容內(nèi)存則需要重啟云主機(jī),在按計(jì)劃擴(kuò)容升級(jí)執(zhí)行主從切換時(shí)意外發(fā)生了數(shù)據(jù)丟失與master進(jìn)入只讀狀態(tài)的故障,這里記錄分享一下。

業(yè)務(wù)redis高可用架構(gòu)

該組業(yè)務(wù)redis使用的是一主一從,通過(guò)sentinel集群實(shí)現(xiàn)故障時(shí)的自動(dòng)主從切換,這套架構(gòu)已經(jīng)平穩(wěn)運(yùn)行數(shù)年,經(jīng)歷住了多次實(shí)戰(zhàn)的考驗(yàn)。

高可用架構(gòu)大體如下圖所示:

簡(jiǎn)單說(shuō)一下sentinel實(shí)現(xiàn)高可用的原理:
集群的多個(gè)(2n+1,N>1)哨兵會(huì)定期輪詢r(jià)edis的所有master/slave節(jié)點(diǎn),如果sentinel集群中超過(guò)一半的哨兵判定redis某個(gè)節(jié)點(diǎn)已經(jīng)主觀下線,就會(huì)將其判定為客觀下線進(jìn)行相應(yīng)處理:

  • 如果下線節(jié)點(diǎn)是master,選定一個(gè)正常work的slave將其選定為新的master節(jié)點(diǎn)。
  • 如果下線節(jié)點(diǎn)是slave,將其從slave節(jié)點(diǎn)中移除。

如果已經(jīng)被客觀下線的節(jié)點(diǎn)恢復(fù)了正常,sentinel中超過(guò)一半哨兵確認(rèn)后則將其加回可用的slave節(jié)點(diǎn)。
所有需要讀寫(xiě)redis的server并不需要直接寫(xiě)死redis 主從配置,而是通過(guò)訪問(wèn)sentinel獲取當(dāng)前redis的主從可用狀態(tài),具體實(shí)現(xiàn)方式可以定時(shí)查詢sentinel詢問(wèn)更新,也可以通過(guò)訂閱機(jī)制讓sentinel在主從變動(dòng)時(shí)主動(dòng)通知訂閱方更新。
sentinel實(shí)現(xiàn)高可用的詳細(xì)原理這里不做過(guò)多贅述,有興趣的小伙伴可以移步參考文獻(xiàn)中的相關(guān)資料。

具體內(nèi)存擴(kuò)容流程

sentinel可以在檢測(cè)到故障時(shí)自動(dòng)切換redis主從,也可以主動(dòng)執(zhí)行sentinel failover mastername 命令實(shí)現(xiàn)手動(dòng)切換主從,所以這次的內(nèi)存擴(kuò)容重啟流程設(shè)計(jì)如下(A代表初始master所在云主機(jī),B代表初始slave所在云主機(jī)):

  • 升級(jí)主機(jī)B內(nèi)存配置,重啟主機(jī)B
  • 檢查B重啟后其上的redis slave是否重新同步master數(shù)據(jù)完成,包括:
    2.1 查看slave redis log是否異常,無(wú)異常pass
    2.2 使用info keyspace命令check master、slave 各db key數(shù)量是否一致,無(wú)異常pass
    2.3 在master寫(xiě)入一個(gè)測(cè)試key,在slave上check是否同步成功
    2.4 觀察依賴server log是否有異常
  • 使用sentinel failover mastername命令手動(dòng)主從切換,主機(jī)A變成新slave,主機(jī)B變成新master,根據(jù)以前手動(dòng)切換的經(jīng)驗(yàn)走到這一步基本上就穩(wěn)了--因?yàn)檫@里本質(zhì)上和一次普通主從切換已經(jīng)沒(méi)有區(qū)別了。
  • 升級(jí)主機(jī)A內(nèi)存配置,重啟主機(jī)A,執(zhí)行以下check:
    4.1 查看新slave redis log是否異常
    4.2 使用info keyspace命令check 新master、新slave 各db key數(shù)量是否一致,無(wú)異常pass
    4.3 在新master寫(xiě)入測(cè)試key,在新slave上check是否同步成功
    4.4 觀察依賴server log是否有異常

至此,若以上步驟都正常通過(guò),一個(gè)完美的redis內(nèi)存升級(jí)工作就完成了。

主從切換后數(shù)據(jù)丟失

結(jié)果正是沒(méi)有想過(guò)可能會(huì)出問(wèn)題的步驟3反而出現(xiàn)了問(wèn)題,直接導(dǎo)致了主從切換后丟掉了部分?jǐn)?shù)據(jù),并且新master進(jìn)入只讀狀態(tài)將近十分鐘。

當(dāng)時(shí)的情況是這樣的:

在執(zhí)行完步驟3后,check 新slave redis log無(wú)異常,正在考慮觀察一會(huì)兒后執(zhí)行主機(jī)A的升級(jí)重啟操作,api的分鐘級(jí)別異常監(jiān)控觸發(fā)了一小波redis相關(guān)報(bào)警。第一反應(yīng)在新master與新slave上執(zhí)行了info keyspace查看key數(shù)量是否已經(jīng)不一致,結(jié)果發(fā)現(xiàn)master/slave的key數(shù)量是一致的--但是再仔細(xì)一看:和切換前的key總數(shù)百萬(wàn)級(jí)相比切換后key總數(shù)降到了十萬(wàn)級(jí)--大部分key數(shù)據(jù)被丟失了。

查看新master、新slave log都沒(méi)有發(fā)現(xiàn)明顯log可以解釋為什么主從切換后會(huì)丟失一大半數(shù)據(jù)這一現(xiàn)象,這時(shí)小伙伴第一次提到了是不是內(nèi)存不夠了,當(dāng)時(shí)自己略一思考馬上回復(fù)到:新master剛升級(jí)了內(nèi)存,不可能內(nèi)容擴(kuò)大后反而內(nèi)存不足的,所以應(yīng)該不是這個(gè)問(wèn)題。

n分鐘后...

小伙伴再一次提出了是不是maxmemory問(wèn)題,這一下子點(diǎn)中了關(guān)鍵點(diǎn),馬上想到主機(jī)B升級(jí)了內(nèi)存是不會(huì)有系統(tǒng)層面內(nèi)存不足的問(wèn)題,但是redis的內(nèi)存使用實(shí)際上還會(huì)受到maxmemory參數(shù)限制,馬上在新master上執(zhí)行config get maxmemory, 只有3GB,而升級(jí)前數(shù)據(jù)實(shí)際使用內(nèi)存超過(guò)了6GB!

立刻調(diào)大了新master的maxmemory參數(shù),redis很快恢復(fù)了可讀寫(xiě)正常狀態(tài),一大波redis只讀引發(fā)的告警通知開(kāi)始快速下降。

原因定位

緊張又刺激的故障處理就這么過(guò)去了,在優(yōu)先處理完丟失key數(shù)據(jù)恢復(fù)工作之后,開(kāi)始回顧整理故障的詳細(xì)原因,總共有如下幾個(gè)疑問(wèn):

  • 明確記得上個(gè)月給主機(jī)A、B上的redis都通過(guò)config set maxmemory設(shè)置為了7GB,為什么出現(xiàn)問(wèn)題時(shí)查詢B上redis 的maxmemory配置卻變成了3GB?
  • 如果主機(jī)B的maxmemory是3GB,其作為slave時(shí)為什么從master同步超過(guò)6GB的數(shù)據(jù)時(shí)不會(huì)有問(wèn)題?--在主從切換前無(wú)論是查看info keyspace還是在master上寫(xiě)入測(cè)試key同步check都是OK的。
  • 為什么主從切換后主機(jī)B上的key數(shù)據(jù)會(huì)丟失?這個(gè)是因?yàn)閙axmemory設(shè)置過(guò)小,是故障的直接原因。
  • 為什么新master由于maxmemory參數(shù)超限進(jìn)入只讀狀態(tài)且刪除部分?jǐn)?shù)據(jù)后,新master中實(shí)際數(shù)據(jù)占用的大小依然超過(guò)>3GB?

如上四個(gè)疑問(wèn)除了問(wèn)題3已經(jīng)明確了,剩下三個(gè)問(wèn)題都讓人疑惑--事出詭異必有妖,經(jīng)過(guò)一番探尋得出其答案:

  • 上個(gè)月修改redis maxmemory時(shí),只通過(guò)config set命令修改了其運(yùn)行時(shí)配置,而沒(méi)有修改對(duì)應(yīng)配置redis.conf上maxmemory的值,主機(jī)B上redis在重啟后就會(huì)從redis.conf上載入該maxmemory,該配置正是3GB,同時(shí)maxmemory參數(shù)是redis節(jié)點(diǎn)獨(dú)立的配置,slave并不會(huì)從master同步該值。
  • 在redis5.0版本之后,redis引入了一個(gè)新的參數(shù)replica-ignore-maxmemory,其官方文檔定義如下:
Maxmemory on replicas
By default, a replica will ignore maxmemory (unless it is promoted to master after a failover or manually). It means that the eviction of keys will be handled by the master, sending the DEL commands to the replica as keys evict in the master side.
This behavior ensures that masters and replicas stay consistent, which is usually what you want. However, if your replica is writable, or you want the replica to have a different memory setting, and you are sure all the writes performed to the replica are idempotent, then you may change this default (but be sure to understand what you are doing).
Note that since the replica by default does not evict, it may end up using more memory than what is set via maxmemory (since there are certain buffers that may be larger on the replica, or data structures may sometimes take more memory and so forth). Make sure you monitor your replicas, and make sure they have enough memory to never hit a real out-of-memory condition before the master hits the configured maxmemory setting.
To change this behavior, you can allow a replica to not ignore the maxmemory. The configuration directives to use is:
replica-ignore-maxmemory no

大意是redis作為slave時(shí)默認(rèn)會(huì)無(wú)視maxmemory參數(shù),這樣可以保證主從的數(shù)據(jù)始終保持一致。當(dāng)master/slave實(shí)際數(shù)據(jù)大小均小于其maxmemory設(shè)置時(shí),這個(gè)參數(shù)沒(méi)有任何影響,而這次丟失數(shù)據(jù)的原因正是因?yàn)橹鳈C(jī)B重啟后作為slave時(shí)maxmemory(3GB)小于實(shí)際數(shù)據(jù)大小(6GB+),此時(shí)replica-ignore-maxmemory 默認(rèn)開(kāi)啟保證作為slave時(shí)直接無(wú)視maxmemory的限制,而當(dāng)執(zhí)行sentinel failover mastername將主機(jī)B切換為新master后,新master不會(huì)受replica-ignore-maxmemory影響,發(fā)現(xiàn)自身maxmemory<實(shí)際數(shù)據(jù)大小后直接開(kāi)始主動(dòng)淘汰key,從而導(dǎo)致了數(shù)據(jù)丟失。

4. 至于主機(jī)B作為master執(zhí)行淘汰key策略并最終進(jìn)入只讀狀態(tài)后,其實(shí)際數(shù)據(jù)大小依然>3GB的原因,則是由于線上redis配置的策略是volatile-lru策略,該策略只會(huì)淘汰有過(guò)期時(shí)間的key,對(duì)于不過(guò)期的key是不淘汰的。

總結(jié)

總的來(lái)看這次故障的根本原因還是個(gè)人對(duì)于redis的配置、操作經(jīng)驗(yàn)不足,如果在調(diào)整運(yùn)行時(shí)maxmemory時(shí)能做到以下二者之一,這次故障就不會(huì)出現(xiàn)了:

  • 調(diào)整運(yùn)行時(shí)maxmemory時(shí)同時(shí)調(diào)整配置文件maxmemory保持一致。
  • 將配置文件maxmemory設(shè)置為0--表示不限制內(nèi)存使用。

正是因?yàn)閷?duì)redis的認(rèn)識(shí)和經(jīng)驗(yàn)不足,沒(méi)有想過(guò)到運(yùn)行時(shí)配置與靜態(tài)配置不一致可能導(dǎo)致的問(wèn)題,這次不可避免的踩坑了。

但是,作為一個(gè)本職RD,半路接手基本靠自學(xué)的兼職運(yùn)維,要考慮到maxmemory的運(yùn)行配置與靜態(tài)配置一致性問(wèn)題好像也確實(shí)不是那么的理所當(dāng)然??。

處理完這次故障后,特意在網(wǎng)上搜索了一番redis主從切換的注意事項(xiàng)、踩坑文章,想看看有沒(méi)有人提到類似的坑,但是并無(wú)所獲,難道這個(gè)坑真的沒(méi)其他人踩(分享)過(guò)?陷入思考...

如果有經(jīng)驗(yàn)豐富的小伙伴看到這里,也歡迎不吝賜教指導(dǎo)一下redis主從的切換的各類常識(shí)與常見(jiàn)大坑!

到此這篇關(guān)于redis主從切換導(dǎo)致的數(shù)據(jù)丟失與陷入只讀狀態(tài)故障解決方案的文章就介紹到這了,更多相關(guān)redis主從切換導(dǎo)致的數(shù)據(jù)丟失內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis?集群模式(Cluster)原理詳解

    Redis?集群模式(Cluster)原理詳解

    redis?cluster集群是一個(gè)由多個(gè)主從節(jié)點(diǎn)集群組成的分布式服務(wù)集群,它具有復(fù)制、高可用和分片特性,cluster集群不需要sentinel?哨兵也能完成節(jié)點(diǎn)移除和故障轉(zhuǎn)移的功能,本文就詳細(xì)的給大家介紹一下Redis?集群模式原理,感興趣的朋友跟著小編一起來(lái)看看吧
    2023-07-07
  • Redis緩存高可用集群詳解

    Redis緩存高可用集群詳解

    Redis集群提供了哨兵模式和高可用集群模式兩種方案,前者適合低并發(fā),配置復(fù)雜,主從切換可能導(dǎo)致瞬斷;后者通過(guò)多主多從結(jié)構(gòu)提高可用性和性能,支持線性擴(kuò)展,配置簡(jiǎn)單,搭建Redis集群至少需要三個(gè)主節(jié)點(diǎn)
    2024-10-10
  • NoSQL和Redis簡(jiǎn)介及Redis在Windows下的安裝和使用教程

    NoSQL和Redis簡(jiǎn)介及Redis在Windows下的安裝和使用教程

    這篇文章主要介紹了NoSQL和Redis簡(jiǎn)介及Redis在Windows下的安裝和使用教程,本文同時(shí)講解了python操作redis,并給出了操作實(shí)例,需要的朋友可以參考下
    2015-01-01
  • redis中hash表內(nèi)容刪除的方法代碼

    redis中hash表內(nèi)容刪除的方法代碼

    在本篇文章里小編給各位整理了關(guān)于redis中hash表內(nèi)容怎么刪除的方法以及技巧代碼,需要的朋友們分享下。
    2019-07-07
  • 安裝redis(windows和Ubuntu)詳解

    安裝redis(windows和Ubuntu)詳解

    這篇文章主要介紹了Redis在Ubuntu和Windows下的安裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Redis搜索日期范圍內(nèi)的查詢示例

    Redis搜索日期范圍內(nèi)的查詢示例

    Redis作為內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)系統(tǒng),雖未專為日期范圍查詢?cè)O(shè)計(jì),但可通過(guò)存儲(chǔ)日期數(shù)據(jù)、使用KEYS命令或有序集合(SortedSet)實(shí)現(xiàn)查詢功能,下面就來(lái)介紹一下
    2024-09-09
  • redis序列化及各種序列化情況劃分

    redis序列化及各種序列化情況劃分

    本文主要介紹了redis序列化及各種序列化情況劃分,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • redis實(shí)現(xiàn)的四種常見(jiàn)限流策略

    redis實(shí)現(xiàn)的四種常見(jiàn)限流策略

    因?yàn)樵诰W(wǎng)站運(yùn)行期間可能會(huì)因?yàn)橥蝗坏脑L問(wèn)量導(dǎo)致業(yè)務(wù)異常、也有可能遭受別人惡意攻,所以我們對(duì)網(wǎng)站要進(jìn)行限流,本文主要介紹了redis四種常見(jiàn)限流策略,感興趣的可以了解一下
    2021-06-06
  • 基于Redis有序集合實(shí)現(xiàn)滑動(dòng)窗口限流的步驟

    基于Redis有序集合實(shí)現(xiàn)滑動(dòng)窗口限流的步驟

    滑動(dòng)窗口算法是一種基于時(shí)間窗口的限流算法,通過(guò)動(dòng)態(tài)地滑動(dòng)窗口,可以動(dòng)態(tài)調(diào)整限流的速率,Redis有序集合可以用來(lái)實(shí)現(xiàn)滑動(dòng)窗口限流,本文介紹基于Redis有序集合實(shí)現(xiàn)滑動(dòng)窗口限流,感興趣的朋友一起看看吧
    2024-12-12
  • 關(guān)于使用Redisson訂閱數(shù)問(wèn)題

    關(guān)于使用Redisson訂閱數(shù)問(wèn)題

    本文主要介紹了關(guān)于使用Redisson訂閱數(shù)問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評(píng)論