MongoDB 複製集原理篇其一
MongoDB作為如今主流的檔案型資料庫,在大小公司都有廣泛的應用。相信對服務有可用性要求的公司,都或多或少會用到複製集功能。複製集正是MongoDB提供的一整套高可用性的解決方案。現階段很多文章都是講述如何建立一個副本集,但是對副本集的原理很少提示。所以,第一篇文章將詳盡的闡述其中各個概念,以便你對複製集功能有個整體的瞭解。
複製集是什麼?
現在假設你執行一個web服務,服務後面連著一個MongoDB例項。如果這個時候例項掛掉了,整個web服務都將不可用,這在生產環境一定是不允許的。那麼如果我們執行多個MongoDB的例項,掛掉一個由另外一個頂上,整個服務的可用性都將大幅提高。這樣的多個例項的集合就稱為複製集
基本架構
MongoDB實現的複製集是主從架構,如下圖所示
在複製集中存在兩種不同型別的節點分別是Primary
(後文用主節點指代)以及Secondary
(後文用從節點指代)。
在一個複製集中只能存在一個主節點,但可以存在多個從節點。從節點不可接受寫入操作,主節點接受寫入操作,通過oplog
的形式,將資料同步給從節點。
oplog
是資料的寫入的日誌。你插入一條記錄,那麼日誌就會增加一行插入操作。從節點拿到日誌,在自己服務上面重放這個操作,就實現了資料的同步。
選舉
當我們的主節點因為意外情況掛掉,其他從節點會選舉出一個節點作為新的主節點。
選舉演演算法採用了著名的分散式演演算法Raft
一般來說選舉會發生在以下幾種情況裡面:
- 複製集新增新節點
- 初始化一個複製集
- 修改了整個叢集的配置
- 從節點和主節點失去連線時間過長(通常預設10s)
Write Concern
當我們只有一臺MongoDB例項的時候,客戶端的一個插入記錄,寫入成功直接返回success。但是,現在我們有一個複製集,那麼客戶端的寫入操作怎麼才算成功寫入呢?
這就要提到MongoDB的寫入配置Write Concern
。Write 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
進行操作重放,增量更新。