最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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ì)定期輪詢(xún)r(jià)edis的所有master/slave節(jié)點(diǎn),如果sentinel集群中超過(guò)一半的哨兵判定redis某個(gè)節(jié)點(diǎn)已經(jīng)主觀(guān)下線(xiàn),就會(huì)將其判定為客觀(guān)下線(xiàn)進(jìn)行相應(yīng)處理:

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

如果已經(jīng)被客觀(guān)下線(xiàn)的節(jié)點(diǎn)恢復(fù)了正常,sentinel中超過(guò)一半哨兵確認(rèn)后則將其加回可用的slave節(jié)點(diǎn)。
所有需要讀寫(xiě)redis的server并不需要直接寫(xiě)死redis 主從配置,而是通過(guò)訪(fǎng)問(wèn)sentinel獲取當(dāng)前redis的主從可用狀態(tài),具體實(shí)現(xiàn)方式可以定時(shí)查詢(xún)sentinel詢(xún)問(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 觀(guān)察依賴(lài)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 觀(guān)察依賴(lài)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ú)異常,正在考慮觀(guān)察一會(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í)查詢(xún)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的原因,則是由于線(xiàn)上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)有人提到類(lèi)似的坑,但是并無(wú)所獲,難道這個(gè)坑真的沒(méi)其他人踩(分享)過(guò)?陷入思考...

如果有經(jīng)驗(yàn)豐富的小伙伴看到這里,也歡迎不吝賜教指導(dǎo)一下redis主從的切換的各類(lèi)常識(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的幾個(gè)過(guò)期策略

    淺談Redis的幾個(gè)過(guò)期策略

    在使用redis時(shí),一般會(huì)設(shè)置一個(gè)過(guò)期時(shí)間,當(dāng)然也有不設(shè)置過(guò)期時(shí)間的,也就是永久不過(guò)期。當(dāng)設(shè)置了過(guò)期時(shí)間,redis是如何判斷是否過(guò)期,以及根據(jù)什么策略來(lái)進(jìn)行刪除的。
    2021-05-05
  • Redis中的有序集合zset從使用到原理分析

    Redis中的有序集合zset從使用到原理分析

    Redis有序集合(zset)是字符串與分值的有序映射,通過(guò)跳躍表和哈希表結(jié)合實(shí)現(xiàn)高效有序性管理,適用于排行榜、延遲隊(duì)列等場(chǎng)景,其時(shí)間復(fù)雜度低,內(nèi)存占用可控,需注意成員大小優(yōu)化及大集合分片處理
    2025-09-09
  • Redis中5種BitMap應(yīng)用場(chǎng)景及實(shí)現(xiàn)介紹

    Redis中5種BitMap應(yīng)用場(chǎng)景及實(shí)現(xiàn)介紹

    Redis BitMap是一種高效的位操作數(shù)據(jù)結(jié)構(gòu),這種結(jié)構(gòu)在處理海量數(shù)據(jù)的布爾型狀態(tài)時(shí)尤其高效,下面小編就來(lái)和大家簡(jiǎn)單介紹一下5種它的應(yīng)用場(chǎng)景及實(shí)現(xiàn)方法吧
    2025-04-04
  • 如何利用Redis鎖解決高并發(fā)問(wèn)題詳解

    如何利用Redis鎖解決高并發(fā)問(wèn)題詳解

    redis鎖處理高并發(fā)問(wèn)題十分常見(jiàn),下面這篇文章主要給大家介紹了關(guān)于如何使用Redis鎖解決高并發(fā)問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • Redis的RDB持久化使用及說(shuō)明

    Redis的RDB持久化使用及說(shuō)明

    這篇文章主要介紹了Redis的RDB持久化使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-12-12
  • 在redhat6.4安裝redis集群【教程】

    在redhat6.4安裝redis集群【教程】

    這篇文章主要介紹了在redhat6.4安裝redis集群【教程】,需要的朋友可以參考下
    2016-05-05
  • redis限流的實(shí)際應(yīng)用

    redis限流的實(shí)際應(yīng)用

    這篇文章主要介紹了redis限流的實(shí)際應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Redis集群設(shè)置密碼訪(fǎng)問(wèn)的實(shí)現(xiàn)

    Redis集群設(shè)置密碼訪(fǎng)問(wèn)的實(shí)現(xiàn)

    本文檔介紹了在Redis集群上配置和管理密碼,包括為每個(gè)節(jié)點(diǎn)添加requirepass配置以啟用密碼保護(hù),及通過(guò)redis-cli關(guān)閉集群時(shí)使用密碼,感興趣的可以了解一下
    2025-08-08
  • Redis 旁路緩存深度解析

    Redis 旁路緩存深度解析

    旁路緩存是 Redis 最常用的緩存策略,本文主要介紹了Redis旁路緩存深度解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-04-04
  • redis批量刪除namespace下的數(shù)據(jù)實(shí)現(xiàn)

    redis批量刪除namespace下的數(shù)據(jù)實(shí)現(xiàn)

    在開(kāi)發(fā)中為了更好的管理數(shù)據(jù),對(duì)redis進(jìn)行了分組存儲(chǔ)操作,在存值時(shí)加了命名空間來(lái)實(shí)現(xiàn),本文就來(lái)詳細(xì)的介紹一下redis批量刪除namespace下的數(shù)據(jù)實(shí)現(xiàn),感興趣的可以了解一下
    2026-03-03

最新評(píng)論

喀什市| 清水县| 泰安市| 江门市| 逊克县| 田东县| 新郑市| 龙泉市| 丹寨县| 富裕县| 永丰县| 山东省| 建德市| 开封县| 井冈山市| 家居| 新民市| 塔河县| 邓州市| 龙陵县| 武功县| 乌拉特前旗| 且末县| 普兰店市| 康平县| 东光县| 密山市| 高雄市| 永清县| 囊谦县| 石屏县| 双柏县| 东乌珠穆沁旗| 新乡县| 基隆市| 昭通市| 满洲里市| 观塘区| 台江县| 凤阳县| 巴南区|