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

Redis腦裂導(dǎo)致數(shù)據(jù)丟失的解決

 更新時間:2023年01月25日 10:28:46   作者:JavaEdge.  
本文主要介紹了Redis腦裂導(dǎo)致數(shù)據(jù)丟失的解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1 案例

主從集群有1個主庫、5個從庫和3個哨兵實例,突然發(fā)現(xiàn)客戶端發(fā)送的一些數(shù)據(jù)丟了,直接影響業(yè)務(wù)層數(shù)據(jù)可靠性。

最終排查發(fā)現(xiàn)是主從集群中的腦裂問題導(dǎo)致:主從集群中,同時有兩個主節(jié)點都能接收寫請求。

影響

客戶端不知道應(yīng)往哪個主節(jié)點寫數(shù)據(jù),導(dǎo)致不同客戶端往不同主節(jié)點寫數(shù)據(jù)。嚴重的,腦裂會進一步導(dǎo)致數(shù)據(jù)丟失。

2 腦裂原因

最初問題:在主從集群中,客戶端發(fā)送的數(shù)據(jù)丟失了。

2.1 為什么數(shù)據(jù)會丟失?

① 確認數(shù)據(jù)同步是否異常

在主從集群中發(fā)生數(shù)據(jù)丟失,最常見原因:主庫數(shù)據(jù)還沒同步到從庫,結(jié)果主庫故障,等從庫升級為主庫后,未同步數(shù)據(jù)丟了。

新寫入主庫的數(shù)據(jù)a=1、b=3,因為在主庫故障前未同步到從庫,失了。

這種數(shù)據(jù)丟失case,可直接對比主從庫的復(fù)制進度差值:

master_repl_offset - slave_repl_offset

若從庫的slave_repl_offset < 原主庫的master_repl_offset,則可認定數(shù)據(jù)丟失是由數(shù)據(jù)同步未完成導(dǎo)致。

部署主從集群時,也監(jiān)測了:

  • 主庫的master_repl_offset
  • 從庫上的slave_repl_offset

但發(fā)現(xiàn)數(shù)據(jù)丟失后,檢查了新主庫升級前的slave_repl_offset,以及原主庫的master_repl_offset,一致,說明該升級為新主庫的從庫,在升級時已和原主庫的數(shù)據(jù)一致。

那為啥還會出現(xiàn)客戶端發(fā)的數(shù)據(jù)丟失?

所有數(shù)據(jù)操作都是從客戶端發(fā)給Redis實例,是否可從客戶端操作日志發(fā)現(xiàn)問題?

② 排查客戶端的操作日志,發(fā)現(xiàn)腦裂現(xiàn)象

發(fā)現(xiàn)主從切換后的一段時間,有個客戶端仍在和原主庫通信,并沒有和升級的新主庫交互。

相當(dāng)于主從集群中同時有兩個主庫。據(jù)此,想到主從集群故障的腦裂。但不同客戶端給兩個主庫發(fā)送數(shù)據(jù)寫操作,應(yīng)只會導(dǎo)致新數(shù)據(jù)會分布在不同主庫,而不會造成數(shù)據(jù)丟失。

思路又斷了。“從原理出發(fā)是追本溯源的好方法”。腦裂是發(fā)生在主從切換過程,猜測是漏掉了主從集群切換過程中的某環(huán)節(jié),所以,聚焦主從切換的執(zhí)行過程。

③ 發(fā)現(xiàn)是原主庫假故障導(dǎo)致的腦裂

我們采用哨兵機制進行主從切換的,主從切換發(fā)生時,一定有超過預(yù)設(shè)數(shù)量(quorum配置項)的哨兵實例和主庫的心跳都超時,才會把主庫判斷為客觀下線,然后,哨兵開始執(zhí)行切換操作。

哨兵切換完成后,客戶端會和新主庫通信,發(fā)送請求操作。

但切換過程中,既然客戶端仍和原主庫通信,說明原主庫并未真故障(如主庫進程掛掉)。懷疑主庫某些原因無法處理請求,也沒響應(yīng)哨兵的心跳,被哨兵錯判客觀下線。
被判下線后,原主庫又重新開始處理請求了,而此時,哨兵還沒完成主從切換,客戶端仍可和原主庫通信,客戶端發(fā)送的寫操作就會在原主庫寫數(shù)據(jù)。

為驗證原主庫只是“假故障”,查看原主庫服務(wù)器的資源使用監(jiān)控。原主庫所在機器有段時間CPU利用率飆升,因某程序把機器CPU用滿,導(dǎo)致Redis主庫無法響應(yīng)心跳,這期間,哨兵就把主庫判為客觀下線,開始主從切換。這程序很快恢復(fù)正常,CPU使用率也下來了。原主庫又繼續(xù)正常服務(wù)請求。

正因原主庫未真故障,在客戶端操作日志中就看到和原主庫通信記錄。從庫被升級為新主庫后,主從集群里就有兩個主庫,這就是案例腦裂原因。

3 為何腦裂會導(dǎo)致數(shù)據(jù)丟失?

主從切換后,從庫一旦升級為新主,哨兵就會讓原主庫執(zhí)行slave of命令,和新主重新進行全量同步。

在全量同步執(zhí)行最后階段,原主需清空本地數(shù)據(jù),加載新主發(fā)送的RDB文件,原主在主從切換期間保存的新寫數(shù)據(jù)就丟了。

主從切換過程中,若原主只是“假故障”,會觸發(fā)哨兵啟動主從切換,一旦等它從假故障恢復(fù),又開始處理請求,這就和新主共存,導(dǎo)致腦裂。

等哨兵讓原主和新主做全量同步后,原主在切換期間保存的數(shù)據(jù)就丟了。

4 腦裂應(yīng)急方案

主從集群中的數(shù)據(jù)丟失是因為發(fā)生腦裂,必須有應(yīng)對腦裂方案。

問題出在原主假故障后,仍能接收請求,因此,可在主從集群機制的配置項中查找是否有限制主庫接收請求的設(shè)置。Redis提供如下配置項限制主庫的請求處理:

min-replicas-to-write
主庫能進行數(shù)據(jù)同步的最少從庫數(shù)量

min-replicas-max-lag
主從庫間進行數(shù)據(jù)復(fù)制時,從庫給主庫發(fā)送ACK消息的最大延遲(單位s)

分別設(shè)置閾值N和T,倆配置項組合后的要求是:

  • 主庫連接的從庫中至少有N個從庫
  • 和主庫進行數(shù)據(jù)復(fù)制時的ACK消息延遲不能超過T秒

否則,主庫就不會再接收客戶端請求。

即使原主假故障,假故障期間也無法響應(yīng)哨兵心跳,也不能和從庫進行同步,自然就無法和從庫進行ACK確認。這倆配置項組合要求就無法得到滿足,原主庫就會被限制接收客戶端請求,客戶端也就不能在原主庫中寫新數(shù)據(jù)。

等新主上線,就只有新主能接收和處理客戶端請求,此時,新寫的數(shù)據(jù)會被直接寫到新主。而原主會被哨兵降為從庫,即使它的數(shù)據(jù)被清空,也不會有新數(shù)據(jù)的丟失。

假設(shè)

  • min-replicas-to-write=1
  • min-replicas-max-lag設(shè)為12s
  • 哨兵的down-after-milliseconds設(shè)為10s

主庫因某原因卡住15s,導(dǎo)致哨兵判斷主庫客觀下線,開始進行主從切換。
同時,因原主庫卡住15s,沒有一個從庫能和原主庫在12s內(nèi)進行數(shù)據(jù)復(fù)制,原主庫也無法接收客戶端請求。
主從切換完成后,也只有新主庫能接收請求,不會發(fā)生腦裂,也就不會發(fā)生數(shù)據(jù)丟失。

5 總結(jié)

腦裂,主從集群中,同時有兩個主能接收寫請求。Redis主從切換過程中,若發(fā)生腦裂,客戶端數(shù)據(jù)就會寫入原主,若原主被降為從庫,這些新寫入數(shù)據(jù)就丟了。

腦裂主要是因為原主庫發(fā)生了假故障,假故障的原因:

  • 和主庫部署在同一臺服務(wù)器上的其他程序臨時占用了大量資源(例如CPU資源),導(dǎo)致主庫資源使用受限,短時間內(nèi)無法響應(yīng)心跳。其它程序不再使用資源時,主庫又恢復(fù)正常
  • 主庫自身遇到阻塞,如處理bigkey或是發(fā)生內(nèi)存swap(你可以復(fù)習(xí)下第19講中總結(jié)的導(dǎo)致實例阻塞的原因),短時間內(nèi)無法響應(yīng)心跳,等主庫阻塞解除后,又恢復(fù)正常的請求處理了。

應(yīng)對腦裂,你可以在主從集群部署時,通過合理地配置參數(shù)min-slaves-to-write和min-slaves-max-lag,來預(yù)防腦裂。

在實際應(yīng)用中,可能會因為網(wǎng)絡(luò)暫時擁塞導(dǎo)致從庫暫時和主庫的ACK消息超時。在這種情況下,并不是主庫假故障,我們也不用禁止主庫接收請求。

6 最佳實踐

假設(shè)從庫有K個,可將:

  • min-slaves-to-write設(shè)置為K/2+1(如果K等于1,就設(shè)為1)
  • min-slaves-max-lag設(shè)置為十幾秒(例如10~20s)

這個配置下,如果有一半以上的從庫和主庫進行的ACK消息延遲超過十幾s,我們就禁止主庫接收客戶端寫請求。

這樣一來,我們可以避免腦裂帶來數(shù)據(jù)丟失的情況,而且,也不會因為只有少數(shù)幾個從庫因為網(wǎng)絡(luò)阻塞連不上主庫,就禁止主庫接收請求,增加了系統(tǒng)的魯棒性。

假設(shè):

  • min-slaves-to-write 置 1
  • min-slaves-max-lag 設(shè)置為 15s,哨兵的
  • down-after-milliseconds 設(shè)置為 10s
    哨兵主從切換需要 5s,主庫因為某些原因卡住12s,此時,還會發(fā)生腦裂嗎?主從切換完成后,數(shù)據(jù)會丟失嗎?

主庫卡住 12s,達到哨兵設(shè)定的切換閾值,所以哨兵會觸發(fā)主從切換。但哨兵切換時間5s,即哨兵還未切換完成,主庫就會從阻塞狀態(tài)中恢復(fù)回來,且沒有觸發(fā) min-slaves-max-lag 閾值,所以主庫在哨兵切換剩下的 3s 內(nèi),依舊可以接收客戶端的寫操作,如果這些寫操作還未同步到從庫,哨兵就把從庫提升為主庫了,那么此時也會出現(xiàn)腦裂的情況,之后舊主庫降級為從庫,重新同步新主庫的數(shù)據(jù),新主庫也會發(fā)生數(shù)據(jù)丟失。

即使 Redis 配置了 min-slaves-to-write 和 min-slaves-max-lag,當(dāng)腦裂發(fā)生時,還是無法嚴格保證數(shù)據(jù)不丟失,只是盡量減少數(shù)據(jù)的丟失。

這種情況下,新主庫之所以會發(fā)生數(shù)據(jù)丟失,是因為舊主庫從阻塞中恢復(fù)過來后,收到的寫請求還沒同步到從庫,從庫就被哨兵提升為主庫了。如果哨兵在提升從庫為新主庫前,主庫及時把數(shù)據(jù)同步到從庫了,那么從庫提升為主庫后,也不會發(fā)生數(shù)據(jù)丟失。但這種臨界點的情況還是有發(fā)生的可能性,因為 Redis 本身不保證主從同步的強一致。

還有一種腦裂情況,就是網(wǎng)絡(luò)分區(qū):主庫和客戶端、哨兵和從庫被分割成了 2 個網(wǎng)絡(luò),主庫和客戶端處在一個網(wǎng)絡(luò)中,從庫和哨兵在另一個網(wǎng)絡(luò)中,此時哨兵也會發(fā)起主從切換,出現(xiàn) 2 個主庫的情況,而且客戶端依舊可以向舊主庫寫入數(shù)據(jù)。等網(wǎng)絡(luò)恢復(fù)后,主庫降級為從庫,新主庫丟失了這期間寫操作的數(shù)據(jù)。

腦裂本質(zhì)是,Redis 主從集群內(nèi)部沒有通過共識算法,來維護多個節(jié)點數(shù)據(jù)的強一致性。不像 Zookeeper,每次寫請求必須大多數(shù)節(jié)點寫成功后才認為成功。當(dāng)腦裂發(fā)生時,Zookeeper 主節(jié)點被孤立,此時無法寫入大多數(shù)節(jié)點,寫請求會直接返回失敗,因此它可以保證集群數(shù)據(jù)的一致性。

對于min-slaves-to-write,如果只有 1 個從庫,當(dāng)把 min-slaves-to-write 設(shè)置為 1 時,在運維時需要小心一些,當(dāng)日常對從庫做維護時,例如更換從庫的實例,需要先添加新的從庫,再移除舊的從庫才可以,或者使用 config set 修改 min-slaves-to-write 為 0 再做操作,否則會導(dǎo)致主庫拒絕寫,影響到業(yè)務(wù)。

到此這篇關(guān)于Redis腦裂導(dǎo)致數(shù)據(jù)丟失的解決的文章就介紹到這了,更多相關(guān)Redis腦裂內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis內(nèi)存回收用法及說明

    Redis內(nèi)存回收用法及說明

    Redis通過配置文件設(shè)置最大內(nèi)存空間,當(dāng)達到上限時,會使用過期策略和淘汰策略來管理內(nèi)存,過期策略包括惰性刪除和周期刪除,而淘汰策略則根據(jù)內(nèi)存使用情況主動刪除部分key以釋放空間
    2025-12-12
  • antd為Tree組件標題附加操作按鈕功能

    antd為Tree組件標題附加操作按鈕功能

    這篇文章主要介紹了antd為Tree組件標題附加操作按鈕功能,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • 深入探究RedisJSON模塊的工作原理以及使用操作

    深入探究RedisJSON模塊的工作原理以及使用操作

    Redis推出了RedisJSON模塊,它允許開發(fā)者在Redis數(shù)據(jù)庫中直接存儲、查詢和處理JSON數(shù)據(jù),本文將詳細介紹RedisJSON的工作原理、關(guān)鍵操作、性能優(yōu)勢以及使用場景,需要的朋友可以參考下
    2024-05-05
  • 基于Redis位圖實現(xiàn)系統(tǒng)用戶登錄統(tǒng)計

    基于Redis位圖實現(xiàn)系統(tǒng)用戶登錄統(tǒng)計

    這篇文章主要介紹了基于Redis位圖實現(xiàn)系統(tǒng)用戶登錄統(tǒng)計,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • CentOS8.4安裝Redis6.2.6的詳細過程

    CentOS8.4安裝Redis6.2.6的詳細過程

    本文給大家介紹CentOS8.4安裝Redis6.2.6的詳細過程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11
  • Redis的數(shù)據(jù)過期策略和數(shù)據(jù)淘汰策略

    Redis的數(shù)據(jù)過期策略和數(shù)據(jù)淘汰策略

    本文主要介紹了Redis的數(shù)據(jù)過期策略和數(shù)據(jù)淘汰策略,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • Redis數(shù)據(jù)結(jié)構(gòu)類型示例解析

    Redis數(shù)據(jù)結(jié)構(gòu)類型示例解析

    這篇文章主要為大家介紹了Redis數(shù)據(jù)結(jié)構(gòu)類型示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 在redis中存儲ndarray的示例代碼

    在redis中存儲ndarray的示例代碼

    在Redis中存儲NumPy數(shù)組(ndarray)通常需要將數(shù)組轉(zhuǎn)換為二進制格式,然后將其存儲為字符串,這篇文章給大家介紹了在redis中存儲ndarray的示例代碼,感興趣的朋友一起看看吧
    2024-02-02
  • Redis+自定義注解+AOP實現(xiàn)聲明式注解緩存查詢的示例

    Redis+自定義注解+AOP實現(xiàn)聲明式注解緩存查詢的示例

    實際項目中,會遇到很多查詢數(shù)據(jù)的場景,這些數(shù)據(jù)更新頻率也不是很高,一般我們在業(yè)務(wù)處理時,會對這些數(shù)據(jù)進行緩存,本文主要介紹了Redis+自定義注解+AOP實現(xiàn)聲明式注解緩存查詢的示例,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • 一文詳解消息隊列中為什么不用redis作為隊列

    一文詳解消息隊列中為什么不用redis作為隊列

    這篇文章主要介紹了消息隊列中為什么不用redis作為隊列的相關(guān)資料,文章詳細介紹了Redis的List和Pub/Sub數(shù)據(jù)類型在隊列中的應(yīng)用,包括如何處理消息積壓和數(shù)據(jù)丟失等問題,通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-12-12

最新評論

宝兴县| 灵石县| 乌兰县| 霸州市| 延吉市| 湖口县| 嘉定区| 淳安县| 六安市| 尚义县| 禄劝| 抚远县| 南皮县| 苏尼特右旗| 尼木县| 石景山区| 玛沁县| 麻栗坡县| 桐梓县| 万安县| 丰镇市| 彭州市| 濉溪县| 于田县| 凤阳县| 阿克苏市| 万安县| 弥渡县| 黎川县| 岐山县| 岑溪市| 石狮市| 蒲江县| 柏乡县| 宿州市| 洪湖市| 闵行区| 泰安市| 临城县| 饶河县| 阳信县|