天天看點

MongoDB 複制相關介紹

上一篇文章介紹了MongoDB的yum安裝方式、配置檔案、建立使用者等基礎知識,本篇介紹MongoDB的源碼安裝以及複制集相關!

一、使用源碼安裝MongoDB

官網下載下傳位址:http://www.mongodb.org/downloads

二、配置MongoDB的複制(主從複制)

1、什麼是複制

  MongoDB複制是将資料同步在多個伺服器的過程。複制提供了資料的備援備份,并在多個伺服器上存儲資料副本,提高了資料的可用性, 并可以保證資料的安全性。複制還允許您從硬體故障和服務中斷中恢複資料。

  Mongodb複制集由一組Mongod執行個體(程序)組成,包含一個Primary節點和多個Secondary節點,Mongodb Driver(用戶端)的所有資料都寫入Primary,Secondary從Primary同步寫入的資料,以保持複制集内所有成員存儲相同的資料集,提供資料的高可用。

2、配置複制的優點

保障資料的安全性

資料高可用性 (24*7)

災難恢複

無需停機維護(如備份,重建索引,壓縮)

分布式讀取資料

3、MongoDB複制原理

mongodb的複制至少需要兩個節點。其中一個是主節點,負責處理用戶端請求,其餘的都是從節點,負責複制主節點上的資料。mongodb各個節點常見的搭配方式為:一主一從、一主多從。

主節點記錄在其上的所有操作oplog,從節點定期輪詢主節點擷取這些操作,然後對自己的資料副本執行這些操作,進而保證從節點的資料與主節點一緻,如下圖:

MongoDB 複制相關介紹

注:以上圖檔參考自網際網路。

大緻流程是:用戶端從主節點讀取資料,在用戶端寫入資料到主節點時,主節點與從節點進行資料互動保障資料的一緻性。

4、配置MongoDB的主從複制(不常用)

主IP:10.0.18.144 從IP:10.0.18.145

注:複制集已經在大多數場合下替代了master-slave複制。如果可能的話,盡可能使用複制集而不是主-從複制架構。本文旨在于為之前遺留的主從架構提供支援,或是僅用于學習。

三、MongoDB副本集的一些特征介紹

1、副本集特征:

N個節點的叢集

任何節點可作為主節點

所有寫入操作都在主節點上

自動故障轉移

自動恢複

2、Primary選舉

複制集通過replSetInitiate指令(或mongo shell的rs.initiate())進行初始化,初始化後各個成員間開始發送心跳消息,

并發起Priamry選舉操作,獲得『大多數』成員投票支援的節點,會成為Primary,其餘節點成為Secondary

3、大多數的定義

假設複制集内投票成員(後續介紹)數量為N,則大多數為N/2 + 1,當複制集記憶體活成員數量不足大多數時,整個複制集将無法選舉出Primary,複制集将無法提供寫服務,處于隻讀狀态。如下圖:

MongoDB 複制相關介紹

通常建議将複制內建員數量設定為奇數,從上表可以看出3個節點和4個節點的複制集都隻能容忍1個節點失效,從『服務可用性』的角度看,其效果是一樣的(但無疑4個節點能提供更可靠的資料存儲)

4、特殊的Secondary

正常情況下,複制集的Seconary會參與Primary選舉(自身也可能會被選為Primary),并從Primary同步最新寫入的資料,以保證與Primary存儲相同的資料。Secondary可以提供讀服務,增加Secondary節點可以提供複制集的讀服務能力,同時提升複制集的可用性。另外,Mongodb支援對複制集的Secondary節點進行靈活的配置,以适應多種場景的需求

5、Arbiter 仲裁節點

Arbiter節點隻參與投票,不能被選為Primary,并且不從Primary同步資料。比如你部署了一個2個節點的複制集,1個Primary,1個Secondary,任意節點當機,複制集将不能提供服務了(無法選出Primary),這時可以給複制集添加一個Arbiter節點,即使有節點當機,仍能選出Primary。

Arbiter本身不存儲資料,是非常輕量級的服務,當複制內建員為偶數時,最好加入一個Arbiter節點,以提升複制集可用性。

6、Priority0

Priority0節點的選舉優先級為0,不會被選舉為Primary。比如你跨機房A、B部署了一個複制集,并且想指定Primary必須在A機房,這時可以将B機房的複制內建員Priority設定為0,這樣Primary就一定會是A機房的成員。

(注意:如果這樣部署,最好将『大多數』節點部署在A機房,否則網絡分區時可能無法選出Primary)

7、Vote0

Mongodb 3.0裡,複制內建員最多50個,參與Primary選舉投票的成員最多7個,其他成員(Vote0)的vote屬性必須設定為0,即不參與投票。

8、Hidden

Hidden節點不能被選為主(Priority為0),并且對Driver不可見。

因Hidden節點不會接受Driver的請求,可使用Hidden節點做一些資料備份、離線計算的任務,不會影響複制集的服務。

9、Delayed

Delayed節點必須是Hidden節點,并且其資料落後與Primary一段時間(可配置,比如1個小時)。

因Delayed節點的資料比Primary落後一段時間,當錯誤或者無效的資料寫入Primary時,可通過Delayed節點的資料來恢複到之前的時間點。

10、資料同步

Primary與Secondary之間通過oplog來同步資料,Primary上的寫操作完成後,會向特殊的local.oplog.rs特殊集合寫入一條oplog,Secondary不斷的從Primary取新的oplog并應用。因oplog的資料會不斷增加,local.oplog.rs被設定成為一個capped集合,當容量達到配置上限時,會将最舊的資料删除掉。另外考慮到oplog在Secondary上可能重複應用,oplog必須具有幂等性,即重複應用也會得到相同的結果。

Secondary初次同步資料時,會先進行init sync 從Primary(或其他資料更新的Secondary)同步全量資料,然後不斷通過tailable cursor從Primary的local.oplog.rs集合裡查詢最新的oplog并應用到自身。

init sync過程包含如下步驟:

T1時間,從Primary同步所有資料庫的資料(local除外),通過listDatabases + listCollections + cloneCollection敏指令組合完成,假設T2時間完成所有操作。

從Primary應用[T1-T2]時間段内的所有oplog,可能部分操作已經包含在步驟1,但由于oplog的幂等性,可重複應用。

根據Primary各集合的index設定,在Secondary上為相應集合建立index。(每個集合_id的index已在步驟1中完成)。

oplog集合的大小應根據DB規模及應用寫入需求合理配置,配置得太大,會造成存儲空間的浪費;配置得太小,可能造成Secondary的init sync一直無法成功。比如在步驟1裡由于DB資料太多、并且oplog配置太小,導緻oplog不足以存儲[T1, T2]時間内的所有oplog,這就讓Secondary無法從Primary上同步完整的資料集。

11、修改複制集配置

當需要修改複制集時,比如增加成員、删除成員、或者修改成員配置(如priorty、vote、hidden、delayed等屬性),可通過replSetReconfig指令(rs.reconfig())對複制集進行重新配置。

比如将複制集的第2個成員Priority設定為2,可執行如下指令

cfg = rs.conf();

cfg.members[1].priority = 2;

rs.reconfig(cfg);

細說Primary選舉

Primary選舉除了在複制集初始化時發生,還有如下場景

複制集被reconfig

Secondary節點檢測到Primary當機時,會觸發新Primary的選舉

當有Primary節點主動stepDown(主動降級為Secondary)時,也會觸發新的Primary選舉

Primary的選舉受節點間心跳、優先級、最新的oplog時間等多種因素影響。

12、節點間心跳

複制內建員間預設每2s會發送一次心跳資訊,如果10s未收到某個節點的心跳,則認為該節點已當機;如果當機的節點為Primary,Secondary(前提是可被選為Primary)會發起新的Primary選舉。

節點優先級

每個節點都傾向于投票給優先級最高的節點

優先級為0的節點不會主動發起Primary選舉

當Primary發現有優先級更高Secondary,并且該Secondary的資料落後在10s内,則Primary會主動降級,讓優先級更高的Secondary有成為Primary的機會。

13、Optime

擁有最新optime(最近一條oplog的時間戳)的節點才能被選為主。

14、網絡分區

隻有更大多數投票節點間保持網絡連通,才有機會被選Primary;如果Primary與大多數的節點斷開連接配接,Primary會主動降級為Secondary。

當發生網絡分區時,可能在短時間内出現多個Primary,故Driver在寫入時,最好設定『大多數成功』的政策,這樣即使出現多個Primary,也隻有一個Primary能成功寫入大多數。

15、複制集的讀寫設定(Read Preference)

預設情況下,複制集的所有讀請求都發到Primary,Driver可通過設定Read Preference來将讀請求路由到其他的節點。

primary: 預設規則,所有讀請求發到Primary

primaryPreferred: Primary優先,如果Primary不可達,請求Secondary

secondary: 所有的讀請求都發到secondary

secondaryPreferred:Secondary優先,當所有Secondary不可達時,請求Primary

nearest:讀請求發送到最近的可達節點上(通過ping探測得出最近的節點)

16、Write Concern

預設情況下,Primary完成寫操作即傳回,Driver可通過設定[Write Concern(https://docs.mongodb.org/manual/core/write-concern/)來設定寫成功的規則。

如下的write concern規則設定必須在大多數節點上成功,逾時時間為5s。

db.products.insert(

  { item: "envelopes", qty : 100, type: "Clasp" },

  { writeConcern: { w: majority, wtimeout: 5000 } }

)

17、異常處理(rollback)

當Primary當機時,如果有資料未同步到Secondary,當Primary重新加入時,如果新的Primary上已經發生了寫操作,則舊Primary需要復原部分操作,以保證資料集與新的Primary一緻。

舊Primary将復原的資料寫到單獨的rollback目錄下,資料庫管理者可根據需要使用mongorestore進行恢複。

四、開始配置MongoDB副本集:

注:這裡使用3台伺服器做MongoDB的副本集,都是源碼安裝的3.4.2版本,架構資訊如下:

主:10.0.18.144  centos6.6  x86_64

從:10.0.18.149  centos6.6  x86_64

從:10.0.18.150  centos6.6  x86_64

具體安裝步驟請參見本篇部落格第一部分!

說明:由上面可知,當權重更高的原主恢複運作了,在新主期間寫入的新資料同樣同步到了原主上,即副本內建功實作了負載均衡的目的。

7、為副本集開啟認證功能

說明:在配置副本集的時候,沒有開啟認證功能,為了安全起見,配置好副本集之後,需要開啟。

注:單伺服器,啟動時添加--auth參或者在配置檔案中配置authorization: enabled開啟開啟驗證。

副本集伺服器,開啟--auth參數或者在配置檔案中配置authorization: enabled的同時,必須指定keyfile參數,節點之間的通訊基于該keyfile,key長度必須在6到1024個字元之間,最好為3的倍數,不能含有非法字元!

五、複制集其他一些用法

本文參考連結:

http://msiyuetian.blog.51cto.com/8637744/1722406

http://www.osyunwei.com/archives/9313.html

http://blog.csdn.net/zhaowenzhong/article/details/51899093

不足之處,請多多指出!