MongoDB複製集(replica set):MongoDB複製集維護相同資料集的一組mongod程式,複製集是生產部署的基礎,具有資料冗餘以及高可用性。
那為什麼要設定複製集(replica set)呢?
- 由於複製集是通過在不同伺服器上儲存來副本,可保證資料在生產部署的冗餘和可靠性,不會因為單點問題而丟失資料。
- 可以通過訪問不同伺服器副本資料來提高資料讀取能力,從而提高整個系統的負載能力。
1. 複製集架構原理
副本集包含多個資料節點和可選的一個仲裁節點。 而在資料節點中:只有一個主節點(primary node),其他節點為為從節點(secondary nodes)。
各個節點成員通過心跳機制進行通訊,當主節點與從節點的通訊的時間超過配置的electionTimeoutMillis期間(預設為10秒)時,符合條件的從節點要求選舉將自己指定為新主節點,群集嘗試完成新主節點的選舉並恢復正常操作。
oplog: 它儲存了修改儲存在資料庫中的資料的所有操作的滾動記錄,MongoDB在主節點伺服器上應用資料庫操作,然後在主節點伺服器的oplog上記錄操作,然後從節點成員在非同步過程中通過心跳機制從任何其他成員匯入oplog並應用這些操作,oplog中的每個操作都是冪等的。所有副本整合員都在local.oplog.rs集合中包含oplog的副本,這允許它們維護資料庫的當前狀態。
從節點: 複製主節點的oplog並將oplog記錄的操作應用於其資料集,如果主節點當機了,將從符合條件的從節點選舉選出新的主節點,。 而且你可以通過配置實現特定的功能,比如:
- 防止從節點成為選舉中的主節點Primary,指定節點優先順序。
- 阻止應用程式從節點讀取資料,從而允許應用程式執行需要與正常流量分離的應用程式,隱藏節點。
- 保留正在執行的“歷史”快照,以用於從某些錯誤中恢復,例如無意中刪除的資料庫,延遲節點
仲裁節點: 仲裁節點不維護資料集。 仲裁節點的目的是通過響應其他副本集節點的心跳和選舉請求來維護副本集中的仲裁。 因為它們不儲存資料集,所以仲裁節點可以是提供副本集仲裁功能的好方法,其資源成本比具有資料集的全功能副本整合員更便宜。 如果您的副本集具有偶數個成員,請新增仲裁節點以獲得主要選舉中的大多數投票。而且仲裁節點總是隻有1次選舉投票,因此允許副本集具有不均勻的投票成員數,而沒有複製資料的額外成員的開銷。
心跳機制(Hearbeat): 複製整合員間預設每2s會傳送一次心跳資訊,如果10s未收到某個節點的心跳,則認為該節點已當機不可以訪問;如果當機的節點為Primary,Secondary(前提是可被選為Primary)會發起新的Primary選舉。仲裁員與其他集合成員之間的唯一溝通是:選舉期間的投票,心跳和配置資料,而且這些交換未加密。資料同步: 為了維護共享資料集的最新副本,副本的從節點設定同步或複製來自其他節點的資料。 MongoDB使用兩種形式的資料同步:初始化同步新節點同步完整的資料集,以及整個叢集節點同步後續資料更改。
其中,初始化同步(Initial Sync)過程:
-
克隆除本地資料庫之外的所有資料庫。 要進行克隆,mongod會掃描每個源資料庫中的每個集合,並將所有資料插入到這些集合的自己的副本中。 初始同步會在為每個集合複製文件時構建所有集合索引。 在早期版本的MongoDB中,在此階段僅構建_id索引。
-
初始同步在資料複製期間提取新新增的oplog記錄。 確保目標成員在本地資料庫中有足夠的磁碟空間,以便在此資料複製階段的持續時間內臨時儲存這些oplog記錄。
-
將所有更改應用於資料集。 使用來自源的oplog,mongod更新其資料集以反映副本集的當前狀態。 初始同步完成後,成員從STARTUP2轉換為SECONDARY。
2. 標準複製集架構
標準複製集架構由三臺伺服器,其中包括三個資料節點(一個主節點、兩個從節點)或兩個資料節點(一個主節點、一個從節點)和一個仲裁節點兩種情況。如下所示:
三個資料節點:
- 一個主節點;
- 兩個從節點,主節點當機後,有機會選舉成為主節點。
兩個資料節點以及一個仲裁節點:
- 一個主節點;
- 一個從節點,有機會被選舉成為主節點;
- 一個仲裁節點,只有投票權利。
3. 節點型別
優先順序0型(Priority 0)節點
優先順序0型節點不可以成為成為主節點,也不能觸發選舉。將從節點配置為優先順序為0以防止它成為主節點,這在多資料中心部署中特別有用,在許多情況下,您無需將備用資料庫設定為優先順序0.但是,在具有不同硬體或地理分佈的副本集中,優先順序為0的備用資料庫可確保僅某些成員成為主資料庫,這樣可以根據實際網路分割槽的網路質量等實際情況進行配置。
例如,一個資料中心承載主資料中心和輔助資料中心:
將第二個資料中心節點優先順序為0只能為從節點資料庫,而資料中心1中的節點才能成為主節點資料庫。(比如你跨機房A、B部署了一個複製集,並且想指定Primary必須在A機房,這時可以將B機房的複製整合員Priority設定為0,這樣Primary就一定會是A機房的成員),隱藏型(Hidden)節點
隱藏型(Hidden)節點:
- 隱藏型從節點是維護主資料集的副本,但對客戶端應用程式不可見。隱藏型從節點適用於具有與副本集中其他成員不同的使用模式。
- 隱藏型從節點必須始終優先為0型從節點,因此不能成為主節點。 隱藏型從節點可能會在選舉中投票。
- 隱藏型從節點將不會收到來自應用程式的請求。我們可以將隱藏型從節點專用於報表節點或是備份節點。
延遲型(Delayed)節點
由於延遲型從節點是資料集的“滾動備份”或執行“歷史”快照,因此它們可以幫助您從各種人為錯誤中恢復。 例如,延遲節點可以從不成功的應用程式升級和操作員錯誤(包括丟棄的資料庫和集合)中恢復。而且延遲型從節點一定是優先順序為0的從節點,也是隱藏型從節點。不能成主節點,也不能給客戶端查詢。
在選擇延遲量時,請考慮延遲量:- 必須等於或大於預期的維護視窗持續時間。
- 必須小於oplog的容量。
投票型(Vote)節點以及不可投票節點
複製集節點可以通過配置members[n].votes來決定該節點是否具有投票權利!members[n].votes值為1具有投票權利為投票型節點,為0則不可以投票即為不可投票節點。無表決權的節點必須優先順序為0,也是優先順序大於0的成員不能為0值。雖然無表決權的成員不在選舉中投票,但這些成員持有副本集資料的副本,並且可以接受來自客戶端應用程式的讀取操作。
另外在副本集最多可包含50個成員,但只有7個投票成員,因此非投票成員允許副本集具有7個以上的成員。並投票成員只有具備以下狀態可以進行投票:
- PRIMARY
- SECONDARY
- STARTUP2
- RECOVERING
- ARBITER
- ROLLBACK
{
"_id" : <num>,
"host" : <hostname:port>,
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 0,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 0
}
複製程式碼
4. 部署結構:
最大投票成員為數量
副本集最多可包含50個成員,但只有7個投票成員。 如果副本集已有7個投票成員,則其他成員必須是非投票成員。
部署奇數個成員
副本集應該確保具有奇數個投票成員,如果您擁有偶數個投票成員,請部署仲裁節點,以便該集合具有奇數個投票成員。仲裁節點不儲存資料的副本並且需要更少的資源。 因此,您可以在應用程式伺服器或其他共享程式上執行仲裁程式。
容錯能力
副本集的容錯是當變為不可用的成員數,並且仍然在副本集中留下足夠的節點成員來選擇主節點成員。容錯是副本集大小的影響, 見下表:
Number of Members | Majority Required to Elect a New Primary | Fault Tolerance |
---|---|---|
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
因此可以得出,將成員新增為偶數個到副本集並不總是會增加容錯能力。但是,在這些情況下,其中將其中一個節點設定成隱藏型和延遲型從節點可以為專用功能提供支援,例如備份或報告。
提高讀負載能力
在具有非常高讀取流量的部署中,您可以通過將讀取分發給從節點來提高讀取吞吐量。 隨著部署的增長,將節點新增或移動到備用資料中心以提高冗餘和可用性。
副本集分佈在兩個或更多資料中心
副本集分佈在兩個或更多資料中心的優勢:
- 如果其中一個資料中心發生故障,資料仍可用於讀取。
- 如果具有少數成員的資料中心發生故障,則副本集仍可以提供寫操作以及讀操作。但是,如果具有大多數成員的資料中心發生故障,則副本集將變為只讀。
在不同地域部署資料節點(具有備用的資料中心)
要在資料中心發生故障時保護您的資料,請在備用資料中心至少保留一個成員。 如果可能,使用奇數個資料中心,並選擇一個成員分佈,以最大限度地提高即使丟失資料中心的可能性,剩餘的副本整合員可以形成可以形成“大多數”選取出主節點,並有提供資料的副本的能力。為確保主資料中心的節點在備用資料中心的成員之前被選為主要成員,請將備用資料中心中節點members[n].priority 設定為低於主資料中節點,如下所示:
根據部署結構部署複製集示例 三個節點成員的副本集,成員合理分佈以及解析如下:
- 兩個資料中心:資料中心1的兩個成員和資料中心2的一個成員。如果副本集的其中一個成員是仲裁者,則將仲裁者分配給具有資料承載成員的資料中心1。
- 如果資料中心1關閉,則副本集將變為只讀。
- 如果資料中心2關閉,則副本集仍然可寫,因為資料中心1中的成員可以進行選舉。
- 三個資料中心:一個成員到資料中心1,一個成員到資料中心2,一個成員到資料中心3。
- 如果任何資料中心發生故障,副本集仍然可寫,因為其餘成員可以舉行選舉。
五副節點成員的副本集,成員合理分佈以及解析如下:
- 兩個資料中心:資料中心1的三個成員和資料中心2的兩個成員。
- 如果資料中心1關閉,則副本集將變為只讀。
- 如果資料中心2關閉,則副本集仍然可寫,因為資料中心1中的成員可以建立多數。
- 三個資料中心:資料中心1的兩個成員,資料中心2的兩個成員和資料中心3的一個成員。
- 如果任何資料中心發生故障,副本集仍然可寫,因為其餘成員可以舉行選舉。
高可用
叢集具有自主選舉能力,影響選取的因子和條件有以下:
- 選取協議
- 心跳機制:複製整合員間預設每2s會傳送一次心跳資訊,如果10s未收到某個節點的心跳,則認為該節點已當機不可以訪問;如果當機的節點為Primary,Secondary(前提是可被選為Primary)會發起新的Primary選舉。
- 節點優先權:每個節點都會傾向於投票給優先順序最高的節點,優先順序為0的節點不能成為主節點Primary,也不會主動發起Primary選舉。當Primary發現有優先順序更高Secondary,並且該Secondary的資料落後在10s內,則Primary會主動降級,讓優先順序更高的Secondary有成為Primary的機會。
- 丟失資料中心:使用分散式副本集,資料中心的丟失可能會影響其他資料中心或資料中心中其餘成員選擇主資料庫的能力。如果可能,在資料中心之間分發副本整合員,以最大限度地提高即使丟失資料中心的可能性,其餘一個副本整合員也可以成為新的主要成員。
- 網路分割槽:只有跟大多數投票節點間能保持網路暢通,才有機會被選主節點Primary;如果Primary與大多數的節點失去聯絡,Primary會主動降級為Secondary。當發生網路分割槽時,可能在短時間內出現多個Primary,故Driver在寫入時,最好設定『大多數成功』的策略,這樣即使出現多個Primary,也只有一個Primary能成功寫入大多數。
5. Write concern和Read Preference
5.1 Write concern
Write concern描述了在操作返回成功之前必須確認寫操作的資料承載成員(即主節點成員和從節點成員,但不是仲裁者)的數量。成員只能在收到併成功應用寫入後才能確認寫入操作。
對於副本集,預設的w:1的Write concern 要求在返回Write concern確認之前,只有Primary主節點確認寫入。您可以指定一個大於1的整數值,以要求來自主節點的確認以及滿足指定值所需的多個從節點,最多為副本集中資料承載成員的總數。
Client 發出帶有需要寫入請求的寫入操作Write concern將等待直到主節點接收來自指定需要寫入詢問所有數量的成員的確認。對於大於1或w:“majority ”的寫入諮詢 Write concern,主節點接收到所需的從節點數量在返回確認可寫入答覆通知client確認寫入。對於w:1的寫入諮詢Write Concern,主要可以在本地應用(單機模式)寫入時立即返回可寫入答覆,因為它有資格對所請求的Write Concern做出判決。
指定超時等待寫入諮詢Write concern的寫操作僅表示所需數量的副本整合員未在wtimeout時間段內確認寫操作。它不一定表示主節點Primary未能應用寫入。
檢驗寫操作
在insert()方法中增加write Concern選項,並指定“大多數”寫入關注和5秒超時,以便操作不會無限期地阻塞,如下:
db.products.insert(
{ item: "envelopes", qty : 100, type: "Clasp" },
{ writeConcern: { w: "majority" , wtimeout: 5000 } }
)
複製程式碼
例如,在3個節點成員的副本集中,操作將需要來自3個成員中的2個的確認。如果稍後縮放副本集以包括兩個額外的投票節點,則相同的操作將需要來自5個副本整合員中的3個的確認。如果主節點伺服器未在wtimeout限制內返回寫入諮詢 Write concern確認,則寫入操作將失敗並出現寫入問題錯誤。
修改預設Write Concern
可以通過在副本集配置中設定settings.getLastErrorDefaults設定來修改副本集的預設寫入問題。配置在返回之前等待寫操作(在大多數投票成員上確認後)操作命令:
cfg = rs.conf()
cfg.settings.getLastErrorDefaults = { w: "majority", wtimeout: 5000 }
rs.reconfig(cfg)
複製程式碼
5.2 Read Preference
Read Preference是mongodb如何將讀操作分配到節點中,預設情況下,應用程式將其讀取操作定向到副本集中的主要成員(即讀取首選項模式“primary”)。 但是,客戶端可以指定讀取首選項以將讀取操作傳送到輔助節點。Read Preference 模式如下:
- primary: 預設規則,所有讀請求發到Primary
- primaryPreferred: Primary優先,如果Primary不可達,請求Secondary
- secondary: 所有的讀請求都發到secondary
- secondaryPreferred:Secondary優先,當所有Secondary不可達時,請求Primary
- nearest:讀請求傳送到最近的可達節點上(通過ping探測得出最近的節點)
以下是使用讀取首選項模式的常見用例:
- 為地理分佈的應用程式提供本地讀取。
- 如果您在多個資料中心中安裝了應用程式伺服器,則可以考慮使用地理位置分散的副本集並使用非主要或最近的讀取首選項。 這允許客戶端從最低延遲成員讀取,而不是始終從主要成員讀取。
- 在故障轉移期間維護可用性。
- 如果希望應用程式在正常情況下從主資料庫讀取,則允許使用primaryPreferred,但在主資料庫不可用時允許從輔助伺服器讀取過時的資料。 這為故障轉移期間的應用程式提供了“只讀模式”。
最後可關注公眾號,一起學習,每天會分享乾貨,還有學習視訊領取!