主頁 > 知識(shí)庫 > MongoDB復(fù)制集原理詳解

MongoDB復(fù)制集原理詳解

熱門標(biāo)簽:河南電話外呼系統(tǒng)招商 智能外呼系統(tǒng)官網(wǎng) 青白江400企業(yè)電話申請(qǐng) 外呼線路資源屬于電信業(yè)務(wù)嗎 小裙科技電銷機(jī)器人怎樣 內(nèi)蒙古營銷智能外呼系統(tǒng)哪個(gè)好 長沙電銷外呼防封卡是什么 crm外呼系統(tǒng)聯(lián)系方式 呼和浩特外呼系統(tǒng)原理是什么

復(fù)制集簡介

Mongodb復(fù)制集由一組Mongod實(shí)例(進(jìn)程)組成,包含一個(gè)Primary節(jié)點(diǎn)和多個(gè)Secondary節(jié)點(diǎn),Mongodb Driver(客戶端)的所有數(shù)據(jù)都寫入Primary,Secondary從Primary同步寫入的數(shù)據(jù),以保持復(fù)制集內(nèi)所有成員存儲(chǔ)相同的數(shù)據(jù)集,提供數(shù)據(jù)的高可用。

下圖(圖片源于Mongodb官方文檔)是一個(gè)典型的Mongdb復(fù)制集,包含一個(gè)Primary節(jié)點(diǎn)和2個(gè)Secondary節(jié)點(diǎn)。

Primary選舉

復(fù)制集通過replSetInitiate命令(或mongo shell的rs.initiate())進(jìn)行初始化,初始化后各個(gè)成員間開始發(fā)送心跳消息,并發(fā)起Priamry選舉操作,獲得『大多數(shù)』成員投票支持的節(jié)點(diǎn),會(huì)成為Primary,其余節(jié)點(diǎn)成為Secondary。

初始化復(fù)制集

config = {
  _id : "my_replica_set",
  members : [
     {_id : 0, host : "rs1.example.net:27017"},
     {_id : 1, host : "rs2.example.net:27017"},
     {_id : 2, host : "rs3.example.net:27017"},
  ]
}

rs.initiate(config)

『大多數(shù)』的定義

假設(shè)復(fù)制集內(nèi)投票成員(后續(xù)介紹)數(shù)量為N,則大多數(shù)為 N/2 + 1,當(dāng)復(fù)制集內(nèi)存活成員數(shù)量不足大多數(shù)時(shí),整個(gè)復(fù)制集將無法選舉出Primary,復(fù)制集將無法提供寫服務(wù),處于只讀狀態(tài)。

投票成員數(shù) 大多數(shù) 容忍失效數(shù)
1 1 0
2 2 0
3 2 1
4 3 1
5 3 2
6 4 2
7 4 3

通常建議將復(fù)制集成員數(shù)量設(shè)置為奇數(shù),從上表可以看出3個(gè)節(jié)點(diǎn)和4個(gè)節(jié)點(diǎn)的復(fù)制集都只能容忍1個(gè)節(jié)點(diǎn)失效,從『服務(wù)可用性』的角度看,其效果是一樣的。(但無疑4個(gè)節(jié)點(diǎn)能提供更可靠的數(shù)據(jù)存儲(chǔ))

特殊的Secondary

正常情況下,復(fù)制集的Seconary會(huì)參與Primary選舉(自身也可能會(huì)被選為Primary),并從Primary同步最新寫入的數(shù)據(jù),以保證與Primary存儲(chǔ)相同的數(shù)據(jù)。

Secondary可以提供讀服務(wù),增加Secondary節(jié)點(diǎn)可以提供復(fù)制集的讀服務(wù)能力,同時(shí)提升復(fù)制集的可用性。另外,Mongodb支持對(duì)復(fù)制集的Secondary節(jié)點(diǎn)進(jìn)行靈活的配置,以適應(yīng)多種場(chǎng)景的需求。

Arbiter

Arbiter節(jié)點(diǎn)只參與投票,不能被選為Primary,并且不從Primary同步數(shù)據(jù)。

比如你部署了一個(gè)2個(gè)節(jié)點(diǎn)的復(fù)制集,1個(gè)Primary,1個(gè)Secondary,任意節(jié)點(diǎn)宕機(jī),復(fù)制集將不能提供服務(wù)了(無法選出Primary),這時(shí)可以給復(fù)制集添加一個(gè)Arbiter節(jié)點(diǎn),即使有節(jié)點(diǎn)宕機(jī),仍能選出Primary。

Arbiter本身不存儲(chǔ)數(shù)據(jù),是非常輕量級(jí)的服務(wù),當(dāng)復(fù)制集成員為偶數(shù)時(shí),最好加入一個(gè)Arbiter節(jié)點(diǎn),以提升復(fù)制集可用性。

Priority0

Priority0節(jié)點(diǎn)的選舉優(yōu)先級(jí)為0,不會(huì)被選舉為Primary

比如你跨機(jī)房A、B部署了一個(gè)復(fù)制集,并且想指定Primary必須在A機(jī)房,這時(shí)可以將B機(jī)房的復(fù)制集成員Priority設(shè)置為0,這樣Primary就一定會(huì)是A機(jī)房的成員。(注意:如果這樣部署,最好將『大多數(shù)』節(jié)點(diǎn)部署在A機(jī)房,否則網(wǎng)絡(luò)分區(qū)時(shí)可能無法選出Primary)

Vote0

Mongodb 3.0里,復(fù)制集成員最多50個(gè),參與Primary選舉投票的成員最多7個(gè),其他成員(Vote0)的vote屬性必須設(shè)置為0,即不參與投票。

Hidden

Hidden節(jié)點(diǎn)不能被選為主(Priority為0),并且對(duì)Driver不可見。

因Hidden節(jié)點(diǎn)不會(huì)接受Driver的請(qǐng)求,可使用Hidden節(jié)點(diǎn)做一些數(shù)據(jù)備份、離線計(jì)算的任務(wù),不會(huì)影響復(fù)制集的服務(wù)。

Delayed

Delayed節(jié)點(diǎn)必須是Hidden節(jié)點(diǎn),并且其數(shù)據(jù)落后與Primary一段時(shí)間(可配置,比如1個(gè)小時(shí))。

因Delayed節(jié)點(diǎn)的數(shù)據(jù)比Primary落后一段時(shí)間,當(dāng)錯(cuò)誤或者無效的數(shù)據(jù)寫入Primary時(shí),可通過Delayed節(jié)點(diǎn)的數(shù)據(jù)來恢復(fù)到之前的時(shí)間點(diǎn)。

數(shù)據(jù)同步

Primary與Secondary之間通過oplog來同步數(shù)據(jù),Primary上的寫操作完成后,會(huì)向特殊的local.oplog.rs特殊集合寫入一條oplog,Secondary不斷的從Primary取新的oplog并應(yīng)用。

因oplog的數(shù)據(jù)會(huì)不斷增加,local.oplog.rs被設(shè)置成為一個(gè)capped集合,當(dāng)容量達(dá)到配置上限時(shí),會(huì)將最舊的數(shù)據(jù)刪除掉。另外考慮到oplog在Secondary上可能重復(fù)應(yīng)用,oplog必須具有冪等性,即重復(fù)應(yīng)用也會(huì)得到相同的結(jié)果。

如下oplog的格式,包含ts、h、op、ns、o等字段

{
 "ts" : Timestamp(1446011584, 2),
 "h" : NumberLong("1687359108795812092"), 
 "v" : 2, 
 "op" : "i", 
 "ns" : "test.nosql", 
 "o" : { "_id" : ObjectId("563062c0b085733f34ab4129"), "name" : "mongodb", "score" : "100" } 
}
  • ts: 操作時(shí)間,當(dāng)前timestamp + 計(jì)數(shù)器,計(jì)數(shù)器每秒都被重置
  • h:操作的全局唯一標(biāo)識(shí)
  • v:oplog版本信息
  • op:操作類型
    • i:插入操作
    • u:更新操作
    • d:刪除操作
    • c:執(zhí)行命令(如createDatabase,dropDatabase)
    • n:空操作,特殊用途
  • ns:操作針對(duì)的集合
  • o:操作內(nèi)容,如果是更新操作
  • o2:操作查詢條件,僅update操作包含該字段

Secondary初次同步數(shù)據(jù)時(shí),會(huì)先進(jìn)行init sync,從Primary(或其他數(shù)據(jù)更新的Secondary)同步全量數(shù)據(jù),然后不斷通過tailable cursor從Primary的local.oplog.rs集合里查詢最新的oplog并應(yīng)用到自身。

init sync過程包含如下步驟

T1時(shí)間,從Primary同步所有數(shù)據(jù)庫的數(shù)據(jù)(local除外),通過listDatabases + listCollections + cloneCollection敏命令組合完成,假設(shè)T2時(shí)間完成所有操作。

從Primary應(yīng)用[T1-T2]時(shí)間段內(nèi)的所有oplog,可能部分操作已經(jīng)包含在步驟1,但由于oplog的冪等性,可重復(fù)應(yīng)用。

根據(jù)Primary各集合的index設(shè)置,在Secondary上為相應(yīng)集合創(chuàng)建index。(每個(gè)集合_id的index已在步驟1中完成)。

oplog集合的大小應(yīng)根據(jù)DB規(guī)模及應(yīng)用寫入需求合理配置,配置得太大,會(huì)造成存儲(chǔ)空間的浪費(fèi);配置得太小,可能造成Secondary的init sync一直無法成功。比如在步驟1里由于DB數(shù)據(jù)太多、并且oplog配置太小,導(dǎo)致oplog不足以存儲(chǔ)[T1, T2]時(shí)間內(nèi)的所有oplog,這就Secondary無法從Primary上同步完整的數(shù)據(jù)集。

修改復(fù)制集配置

當(dāng)需要修改復(fù)制集時(shí),比如增加成員、刪除成員、或者修改成員配置(如priorty、vote、hidden、delayed等屬性),可通過replSetReconfig命令(rs.reconfig())對(duì)復(fù)制集進(jìn)行重新配置。

比如將復(fù)制集的第2個(gè)成員Priority設(shè)置為2,可執(zhí)行如下命令

cfg = rs.conf();
cfg.members[1].priority = 2;
rs.reconfig(cfg);

細(xì)說Primary選舉

Primary選舉除了在復(fù)制集初始化時(shí)發(fā)生,還有如下場(chǎng)景

  • 復(fù)制集被reconfig
  • Secondary節(jié)點(diǎn)檢測(cè)到Primary宕機(jī)時(shí),會(huì)觸發(fā)新Primary的選舉
  • 當(dāng)有Primary節(jié)點(diǎn)主動(dòng)stepDown(主動(dòng)降級(jí)為Secondary)時(shí),也會(huì)觸發(fā)新的Primary選舉

Primary的選舉受節(jié)點(diǎn)間心跳、優(yōu)先級(jí)、最新的oplog時(shí)間等多種因素影響。

節(jié)點(diǎn)間心跳

復(fù)制集成員間默認(rèn)每2s會(huì)發(fā)送一次心跳信息,如果10s未收到某個(gè)節(jié)點(diǎn)的心跳,則認(rèn)為該節(jié)點(diǎn)已宕機(jī);如果宕機(jī)的節(jié)點(diǎn)為Primary,Secondary(前提是可被選為Primary)會(huì)發(fā)起新的Primary選舉。

節(jié)點(diǎn)優(yōu)先級(jí)

  • 每個(gè)節(jié)點(diǎn)都傾向于投票給優(yōu)先級(jí)最高的節(jié)點(diǎn)
  • 優(yōu)先級(jí)為0的節(jié)點(diǎn)不會(huì)主動(dòng)發(fā)起Primary選舉
  • 當(dāng)Primary發(fā)現(xiàn)有優(yōu)先級(jí)更高Secondary,并且該Secondary的數(shù)據(jù)落后在10s內(nèi),則Primary會(huì)主動(dòng)降級(jí),讓優(yōu)先級(jí)更高的Secondary有成為Primary的機(jī)會(huì)。

Optime

擁有最新optime(最近一條oplog的時(shí)間戳)的節(jié)點(diǎn)才能被選為主。

網(wǎng)絡(luò)分區(qū)

只有更大多數(shù)投票節(jié)點(diǎn)間保持網(wǎng)絡(luò)連通,才有機(jī)會(huì)被選Primary;如果Primary與大多數(shù)的節(jié)點(diǎn)斷開連接,Primary會(huì)主動(dòng)降級(jí)為Secondary。當(dāng)發(fā)生網(wǎng)絡(luò)分區(qū)時(shí),可能在短時(shí)間內(nèi)出現(xiàn)多個(gè)Primary,故Driver在寫入時(shí),最好設(shè)置『大多數(shù)成功』的策略,這樣即使出現(xiàn)多個(gè)Primary,也只有一個(gè)Primary能成功寫入大多數(shù)。

復(fù)制集的讀寫設(shè)置

Read Preference

默認(rèn)情況下,復(fù)制集的所有讀請(qǐng)求都發(fā)到Primary,Driver可通過設(shè)置Read Preference來將讀請(qǐng)求路由到其他的節(jié)點(diǎn)。

  • primary: 默認(rèn)規(guī)則,所有讀請(qǐng)求發(fā)到Primary
  • primaryPreferred: Primary優(yōu)先,如果Primary不可達(dá),請(qǐng)求Secondary
  • secondary: 所有的讀請(qǐng)求都發(fā)到secondary
  • secondaryPreferred:Secondary優(yōu)先,當(dāng)所有Secondary不可達(dá)時(shí),請(qǐng)求Primary
  • nearest:讀請(qǐng)求發(fā)送到最近的可達(dá)節(jié)點(diǎn)上(通過ping探測(cè)得出最近的節(jié)點(diǎn))

Write Concern

默認(rèn)情況下,Primary完成寫操作即返回,Driver可通過設(shè)置[Write Concern(https://docs.mongodb.org/manual/core/write-concern/)來設(shè)置寫成功的規(guī)則。

如下的write concern規(guī)則設(shè)置寫必須在大多數(shù)節(jié)點(diǎn)上成功,超時(shí)時(shí)間為5s。

db.products.insert(
 { item: "envelopes", qty : 100, type: "Clasp" },
 { writeConcern: { w: majority, wtimeout: 5000 } }
)

上面的設(shè)置方式是針對(duì)單個(gè)請(qǐng)求的,也可以修改副本集默認(rèn)的write concern,這樣就不用每個(gè)請(qǐng)求單獨(dú)設(shè)置。

cfg = rs.conf()
cfg.settings = {}
cfg.settings.getLastErrorDefaults = { w: "majority", wtimeout: 5000 }
rs.reconfig(cfg)

異常處理(rollback)

當(dāng)Primary宕機(jī)時(shí),如果有數(shù)據(jù)未同步到Secondary,當(dāng)Primary重新加入時(shí),如果新的Primary上已經(jīng)發(fā)生了寫操作,則舊Primary需要回滾部分操作,以保證數(shù)據(jù)集與新的Primary一致。

舊Primary將回滾的數(shù)據(jù)寫到單獨(dú)的rollback目錄下,數(shù)據(jù)庫管理員可根據(jù)需要使用mongorestore進(jìn)行恢復(fù)。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • MongoDB的主從復(fù)制及副本集的replSet配置教程
  • MongoDB在不同主機(jī)間復(fù)制數(shù)據(jù)庫和集合的教程
  • MongoDB的Master-Slave主從模式配置及主從復(fù)制要點(diǎn)解析
  • MongoDB入門教程之主從復(fù)制配置詳解
  • MongoDB 主從復(fù)制實(shí)例講解
  • 詳解mongoDB主從復(fù)制搭建詳細(xì)過程
  • mongodb主從復(fù)制_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
  • Mongodb 副本集搭建問題總結(jié)及解決辦法
  • Mongodb副本集和分片示例詳解
  • MongoDB副本集丟失數(shù)據(jù)的測(cè)試實(shí)例教程
  • MongoDB 復(fù)制(副本集)學(xué)習(xí)筆記

標(biāo)簽:楚雄 白山 舟山 安順 池州 黃石 呼倫貝爾 菏澤

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MongoDB復(fù)制集原理詳解》,本文關(guān)鍵詞  MongoDB,復(fù)制,集,原理,詳解,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MongoDB復(fù)制集原理詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于MongoDB復(fù)制集原理詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章