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

Redis腦裂導致數據丟失的解決

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

1 案例

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

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

影響

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

2 腦裂原因

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

2.1 為什么數據會丟失?

① 確認數據同步是否異常

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

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

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

master_repl_offset - slave_repl_offset

若從庫的slave_repl_offset < 原主庫的master_repl_offset,則可認定數據丟失是由數據同步未完成導致。

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

  • 主庫的master_repl_offset
  • 從庫上的slave_repl_offset

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

那為啥還會出現客戶端發(fā)的數據丟失?

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

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

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

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

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

③ 發(fā)現是原主庫假故障導致的腦裂

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

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

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

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

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

3 為何腦裂會導致數據丟失?

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

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

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

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

4 腦裂應急方案

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

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

min-replicas-to-write
主庫能進行數據同步的最少從庫數量

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

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

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

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

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

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

假設

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

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

5 總結

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

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

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

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

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

6 最佳實踐

假設從庫有K個,可將:

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

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

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

假設:

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

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

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

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

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

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

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

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

相關文章

  • Redis?異常?read?error?on?connection?的解決方案

    Redis?異常?read?error?on?connection?的解決方案

    這篇文章主要介紹了Redis異常read?error?on?connection的解決方案,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08
  • Redis主從復制詳解

    Redis主從復制詳解

    今天小編就為大家分享一篇關于Redis主從復制詳解,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Redis 哨兵高模式搭建及Java代碼配置

    Redis 哨兵高模式搭建及Java代碼配置

    這篇文章主要介紹了Redis 哨兵高模式搭建及Java代碼配置,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Redis實現分布式鎖(setnx、getset、incr)以及如何處理超時情況

    Redis實現分布式鎖(setnx、getset、incr)以及如何處理超時情況

    本文主要介紹了Redis實現分布式鎖(setnx、getset、incr)以及如何處理超時情況,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Redis集群的相關詳解

    Redis集群的相關詳解

    這篇文章主要介紹了Redis集群的相關,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Redis基本數據類型List常用操作命令

    Redis基本數據類型List常用操作命令

    這篇文章主要為大家介紹了Redis數據類型List常用命令操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • Redis中SDS簡單動態(tài)字符串詳解

    Redis中SDS簡單動態(tài)字符串詳解

    Redis中的SDS(Simple?Dynamic?String)是一種自動擴容的字符串實現方式,它可以提供高效的字符串操作,并且支持二進制安全。SDS的設計使得它可以在O(1)時間內實現字符串長度的獲取和修改,同時也可以在O(N)的時間內進行字符串的拼接和截取。
    2023-04-04
  • Redis過期Key刪除策略和內存淘汰策略的實現

    Redis過期Key刪除策略和內存淘汰策略的實現

    當內存使用達到上限,就無法存儲更多數據了,為了解決這個問題,Redis內部會有兩套內存回收的策略,過期Key刪除策略和內存淘汰策略,本文就來詳細的介紹一下這兩種方法,感興趣的可以了解一下
    2024-02-02
  • redis.clients.jedis.exceptions.JedisBusyException無法處理異常的解決方法

    redis.clients.jedis.exceptions.JedisBusyException無法處理異常的解決方法

    redis.clients.jedis.exceptions.JedisBusyException異常通常不是 Jedis客戶端直接拋出的標準異常,本文就來介紹一下異常的解決方法,感興趣的可以了解一下
    2024-05-05
  • Redis安裝圖文教程(Windows和Linux)

    Redis安裝圖文教程(Windows和Linux)

    這篇文章主要介紹了Redis安裝教程(Windows和Linux),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03

最新評論