(2)MongoDB副本集自動故障轉移原理
前文我們搭建MongoDB三成員副本集,瞭解叢集基本特性,今天我們圍繞下圖聊一聊背後的細節。
預設搭建的replica set均在主節點讀寫,輔助節點冗餘部署,形成高可用和備份, 具備自動故障轉移的能力。
叢集心跳保活
叢集每個節點以週期性向其他成員發出心跳命令 replSetHeartbeat來獲取狀態,
根據應答訊息來更新節點的狀態,根據最終狀態確定是否重選主節點。
預設心跳週期 heartbeatIntervalMillis= 2000ms;
認定Primary節點失聯的閾值 electionTimeoutMillis=10s
非同步複製
輔助節點複製主節點的oplog,並將改變應用到資料集,從而保持與主節點資料同步。
這裡有三個知識點:
-
oplog是一個特殊的封頂集合capped collection, 主節點上的operation log會記錄在主節點的oplog中,輔助節點非同步拷貝這些操作,這樣所有的節點的都包含operatin log的一個副本:local.oplog.rs集合
-
每次非同步複製觸發的時機是在心跳保活階段,所有的輔助節點都會在ping階段從其他成員插入oplog文件。
-
oplog中的每個操作都是冥等的:無論是一次還是多次應用到目標資料集,oplog操作會產生相同的結果
刪除和插入操作:
若多次應用刪除操作,後續刪除操作無效果;
若多次應用插入操作,因為每次操作均包含包含_id值,因此它也不會插入文件的第二個副本(因為_id必須是唯一的)。
當有新節點加入叢集,該節點會啟動另一種同步:initial sync, 將所有資料從副本集一個成員拷貝到另外一個成員, 複製完成,會過渡為輔助節點。
選舉主節點
叢集會因為各種事件觸發選舉主節點
-
在叢集中新增新節點
-
初始化replica set叢集
-
執行人工運維命令(rs.stepDown() rs.reconfig())維護叢集
-
輔助節點與主節點失聯時間超過預設10s
自動故障轉移說的是最後一種情況:
預設情況下,輔助節點A與主節點心跳失聯超過10s,A節點標記主節點不可用;之後與其他輔助節點心跳保活,溝通各自資訊(節點的票數、節點優先順序、PingMs等因素)確立出新主節點。
在發生故障轉移時,叢集不能再執行寫入操作; 如果你在客戶端配置了在輔助節點的讀取首選項 read preference,則叢集可繼續提供讀取能力。
你的應用程式可用重試邏輯應對自動故障轉移和後續的重選,從MongoDB3.6版本開始,MongoDB Driver可偵測主節點的失聯,並執行一次重試操作。
適配MongoDB4.2的Driver預設會重試寫入操作;
適配Mongodb4.0-3.6的Driver需顯式在連線字串包含retryWrites = true,以確保主節點失聯時能重試寫入操作。
連線副本集的客戶端配置字串,其中rs0是配置檔案中設定的副本集名稱 replSetName
mongodb://account:[email protected]:27017,mongodb1.example.com:27017,mongodb2.example.com:27017?replicaSet=rs0
OK, 以上便是MongoDB副本集心跳保活、非同步複製、自動故障轉移的背景知識。
留一個作業?
客戶端連線MongoDB副本集的連線字串,只是一個很普通的IP陣列,並未體現主副節點,客戶端是怎麼區分主副節點,並向主節點發出寫入指令。
所有遵守MongoDB官方規範的Driver都會實現 Service discovery和Monitoring, 我們在連線字串指定的IP節點其實是種子節點,Driver會準實時監視叢集,獲取叢集最新的狀態資訊。(heartbeatFrequencyMS 約定了客戶端Driver檢查叢集狀態的時間間隔)
這也與我在MongoDB 輔助節點看到的日誌相互照應。
&n