1. 程式人生 > 程式設計 >MongoDB 複製集原理篇其一

MongoDB 複製集原理篇其一

MongoDB作為如今主流的檔案型資料庫,在大小公司都有廣泛的應用。相信對服務有可用性要求的公司,都或多或少會用到複製集功能。複製集正是MongoDB提供的一整套高可用性的解決方案。現階段很多文章都是講述如何建立一個副本集,但是對副本集的原理很少提示。所以,第一篇文章將詳盡的闡述其中各個概念,以便你對複製集功能有個整體的瞭解。

複製集是什麼?

現在假設你執行一個web服務,服務後面連著一個MongoDB例項。如果這個時候例項掛掉了,整個web服務都將不可用,這在生產環境一定是不允許的。那麼如果我們執行多個MongoDB的例項,掛掉一個由另外一個頂上,整個服務的可用性都將大幅提高。這樣的多個例項的集合就稱為複製集

。當然複製集上的例項,都儲存著相同的資料。

基本架構

MongoDB實現的複製集是主從架構,如下圖所示

在複製集中存在兩種不同型別的節點分別是Primary(後文用主節點指代)以及Secondary(後文用從節點指代)。

在一個複製集中只能存在一個主節點,但可以存在多個從節點。從節點不可接受寫入操作,主節點接受寫入操作,通過oplog的形式,將資料同步給從節點。 oplog是資料的寫入的日誌。你插入一條記錄,那麼日誌就會增加一行插入操作。從節點拿到日誌,在自己服務上面重放這個操作,就實現了資料的同步。

選舉

當我們的主節點因為意外情況掛掉,其他從節點會選舉出一個節點作為新的主節點。

選舉演演算法採用了著名的分散式演演算法Raft
(zh.wikipedia.org/wiki/Raft)。

一般來說選舉會發生在以下幾種情況裡面:

  • 複製集新增新節點
  • 初始化一個複製集
  • 修改了整個叢集的配置
  • 從節點和主節點失去連線時間過長(通常預設10s)

Write Concern

當我們只有一臺MongoDB例項的時候,客戶端的一個插入記錄,寫入成功直接返回success。但是,現在我們有一個複製集,那麼客戶端的寫入操作怎麼才算成功寫入呢?

這就要提到MongoDB的寫入配置Write ConcernWrite Concern是這樣一種k,v結構{ w: <value>,j: <boolean>,wtimeout: <number> }

  • w:

w表示需要多少個節點確認才算寫入成功,預設值為1({'w': 1})。表示寫入Primary節點後就算寫入成功。如果填n表示需要寫入n個節點,才能夠算寫入成功。

w還有另一種選項majority,表示寫入大部分節點算成功寫入。舉個例子,現在有3個節點參與選舉投票,那麼成功寫入2個就算寫入成功。

  • j:

j表示是否需要成功寫入journal files

  • wtimeout:

表示超時時間,這裡需要額外注意,在有的臨界點寫入成功也有可能返回超時。但是MongoDB是不會去回滾寫入成功的資料的。

Write Concern可以直接修改叢集配置

cfg = rs.conf()
cfg.settings.getLastErrorDefaults = { w: "majority",wtimeout: 5000 }
rs.reconfig(cfg)
複製程式碼

也可以增加

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

第二個引數做單獨的配置。

五類從節點

MongoDB的從節點可以大致分為五類:

  • 普通從節點

這類從節點屬於priority為1,可以正常的選舉,複製資料。

  • Priority為0的節點

這類節點只能複製資料,不能被選舉為主節點,也不能觸發選舉的開始。這類節點通常作為跟隨節點。所謂跟隨節點,只儲存資料,當普通節點宕機時,可以迅速替換到主節點。

  • 隱藏節點

隱藏節點對於客戶端是不可見的,隱藏節點的priority一定要為0.

  • 延遲節點

延遲節點不會立即同步主節點的資料,會有個時間上的延遲。比方說7點主節點寫入一條資料,8點延遲節點才會同步這點資料。延遲節點最好設定為隱藏節點,以免客戶端讀取到髒資料。延遲節點的作用,主要是作為備份和回滾使用。

  • 仲裁者節點(Arbiter)

這類節點不含資料,僅僅是作為投票使用。有的時候我們可能有4個節點用來投票,但是投票節點數需要奇數個,就可以部署一臺仲裁者,使投票節點數為奇數。

從節點資料同步

redis相似,資料同步遵循兩種形式,當新節點加入叢集時,為把資料全量傳輸過去。第一次同步過後,會根據oplog進行操作重放,增量更新。