1. 程式人生 > >MongoDB復制集成員及架構介紹(一)

MongoDB復制集成員及架構介紹(一)

bit not -o 服務 復制 誤操作 存儲 帶來 影響

MongoDB復制集介紹

MongoDB支持在多個機器中通過異步復制達到提供了冗余,增加了數據的可用性。MongoDB有兩種類型的復制,第一種是同於MySQL的主從復制模式(MongoDB已不再推薦此方案);第二種是復制集,提供了自動故障轉移的主從復制集群,其中復制集沒有固定的主節點,當一個主機的故障後從節點會重新“選舉”出一個新的主節點,從而提高的系統的可用性。

復制集(Replica Sets)成員

MongoDB的復制集是由一組mongod實例所組成的,並提供了數據冗余與高可用性。復制集中的成員有以下幾種:

1)主節點(PRIMARY)

在復制集中,主節點是唯一能夠接收寫請求的節點。MongoDB在 主節點上進行寫操作,並會將這些操作記錄到主節點的oplog 中。從節點會將oplog復制到其本機並將這些操作應用到其自己的數據集上。

2)從節點(SECONDARY)

從節點通過應用主節點傳來的數據變動操作(oplog日誌文件)來保持其數據集與主節點的一致,這一點跟大多數數據庫的復制模式差不多,但Mongodb的從節點是無法進行寫操作的。此外從節點也可以通過增加額外的參數配置來對應特殊的需求。例如,從節點可以是non-voting 或是priority 0。

3)投票節點(arbiter)

我們也可以為復制集設置一個投票節點,投票節點其本身並不包含數據集副本。且也無法升職為主節點。這裏我們稱arbiter為投票節點,也可以稱為仲裁(arbiter中文就是仲裁),一般在高可用集群中有兩種常見的方式選舉,一個是投票另一個就是仲裁。一個復制集中可能會有多個投票節點來為選舉出新的主節點進行投票,投票節點的存在使得復制集可以以偶數個節點存在,而無需為復制集再新增節點(不要將投票節點運行在復制集的主節點或者從節點機器上)。一旦當前的主節點不可用時,投票節點就會參與到新的主節點選舉的投票中。

註意:

1)一個復制集中所有的成員都有一票投票權利,ARBITER節點從MongoDB2.6開始也只有投一票的權利。但是跟其他成員不同的是,其他成員的投票權是可以通過votes參數給取消掉的,但是ARBITER的投票權是無法取消的。目前副本集節點最多可以有12個(從節點可以分攤讀壓力),其中最多只有7個可以投票,也就是說當你的投票節點大於7個時,就要把其余節點的投票權取消。

2)如果僅僅在復制集成員為偶數個的時候加入投票節點,如果在擁有奇數個復制集成員的復制集中新增了一個投票節點,復制集可能會遇到選舉僵局。在下面這樣的復制集中,一個投票節點可被加入到復制集中來實現選舉過程中所需的偶數張票。

技術分享圖片

另外要說的就是安全性,投票節點與其他復制集節點的交流僅有:選舉過程中的投票,心跳檢測和配置數據,這些交互都是不加密的。當然如果有需求也可以通過開啟authorization來進行安全性保證。

什麽時候應該使用投票節點?

當復制集中有偶數個節點時,應該再加一個投票節點,用於打破投票僵局。比如:我線上共有3臺服務器,其中1臺是作為Web 服務器;其余2臺作為 DB 服務器,各部署了1個MongoDB節點,構成了2個節點的復制集。這個時候,我並沒有多余的機器了。在這個情況下,如果任意一臺 DB 服務器上的 MongoDB 掛了,那麽另外一臺的 MongoDB 必然變為 SECONDARY 節點(這個地方可能有些不太理解,任意一臺掛掉了另外一臺不是應該做主節點嗎?),那麽就意味著 MongoDB 是不可用的了。為了避免這種情況,提高服務的可用性,可以在 Web 服務器上部署一個投票節點。投票節點並不存儲數據,因此不能升職為 PRIMARY 節點,它對於硬件資源要求很低,並不會對 Web 服務器上的其他程序產生太大影響。這種情況下,如果任意一臺 DB 服務器掛了,另外一臺服務器上的 MongoDB 將成為 PRIMARY 節點,此時 MongoDB 還是依舊對外提供服務的。乘此時機,趕緊排查出故障的那臺服務器的原因,盡快恢復服務。

為了讓投票節點可以占用更少的資源,可以在配置文件中添加以下幾個配置項:

1 2 3 journal = false smallfiles = true noprealloc = true

所以一個復制集至少需要這幾個成員:一個主節點 ,一個從節點和一個投票節點。但是在大多數情況下,我們會保持3個擁有數據集的節點:一個主節點和兩個從節點。

技術分享圖片

復制集中任何成員都可以接收讀請求。但是默認情況下,應用程序會直接連接到在主節點上進行讀操作。閱讀復制集讀選項可以獲得更多關於更改默認讀請求目標的信息。復制集最多只能擁有一個主節點,一旦當前的主節點不可用了,復制集就會選舉出新的主節點。

對於復制集從節點來說,還可以有以下幾種多樣性。分別為優先級為0的復制集成員、隱藏節點、延時節點。

優先級為0的復制集成員

一旦將優先級設置為0,那麽該從節點將不能升職為主節點。優先級為0的成員不會觸發選舉。除此之外該節點與其他從節點沒有區別,優先級0的從節點擁有與主節點一致的數據集,能接受讀請求,同時也能參與投票。通過將從節點的優先級設置為0來防止其升職為主節點可以在分布式數據中心的結構中起到很好的作用。

在下述這樣的擁有三個成員的復制集中,一個主節點和一個從節點坐落在某一個數據中心中,另一個不能升職為主節點的優先級為0的從節點則在另一個數據中心。

技術分享圖片

隱藏節點

讀操作

當在一個復制集中設置了隱藏節點,那麽客戶端將不會把讀請求分發到隱藏節點上,即使我們設定了復制集讀選項。這些隱藏節點將不會收到來自應用程序的請求。我們可以將隱藏節點專用於報表節點或是備份節點。延時節點也應該是一個隱藏節點。在分片集群中, mongos 將不與隱藏節點進行交流。

投票

在復制集的選舉中,隱藏節點是會參加投票的。當關閉一個隱藏節點的時候,請確認復制集中的可用節點個數足夠進行選舉,以防主節點降職導致復制集對外不可用。

延時節點

延時節點也將從復制集中主節點復制數據,然而延時節點中的數據集將會比復制集中主節點的數據延後。舉個例子,現在是09:52,如果延時節點延後了1小時,那麽延時節點的數據集中將不會有08:52之後的操作。由於延時節點的數據集是延時的,因此它可以幫助我們在人為誤操作或是其他意外情況下恢復數據。舉個例子,當應用升級失敗,或是誤操作刪除了表和數據庫時,我們可以通過延時節點進行數據恢復。

行為

延時節點通過延時應用 oplog 中的操作來實現其延時的效果。當我們選擇延時時常的時候,需要考慮到以下內容:

1)必須大於或者等於你的維護視窗。

2)必須小於oplog的存儲能力,參見Oplog大小來獲得更多oplog的信息。

分片

在分片集群中,當平衡器打開的時候延時節點效果有限。因為延時節點延時的復制數據段,而若在延時的時間段內進行過數據段遷移的話,復制集中的延時節點就無法為還原分片集群提供有效的幫助了。

使用復制集的好處?

1)備份數據

通過自帶的 mongo_dump/mongo_restore 工具也可以實現備份,但是畢竟沒有復制集的自動同步備份方便。

2)故障自動轉移

部署了復制集,當主節點掛了後,集群會自動投票再從節點中選舉出一個新的主節點,繼續提供服務。而且這一切都是自動完成的,對運維人員和開發人員是透明的。當然,發生故障了還是得人工及時處理,不要過度依賴復制集,萬一都掛了,那就連喘息的時間都沒有了。

3)提高讀性能

默認情況下,讀和寫都只能在主節點上進行。但是主壓力過大時就可以把讀操作分離到從節點上從而提高讀性能。下面是MongoDB的驅動支持5種復制集讀選項:

primary:默認模式,所有的讀操作都在復制集的主節點進行的。

primaryPreferred:在大多數情況時,讀操作在主節點上進行,但是如果主節點不可用了,讀操作就會轉移到從節點上執行。

secondary:所有的讀操作都在復制集的從節點上執行。

secondaryPreferred:在大多數情況下,讀操作都是在從節點上進行的,但是當從節點不可用了,讀操作會轉移到主節點上進行。

nearest:讀操作會在復制集中網絡延時最小的節點上進行,與節點類型無關。

但是除了primary 模式以外的復制集讀選項都有可能返回非最新的數據,因為復制過程是異步的,從節點上應用操作可能會比主節點有所延後。如果我們不使用primary模式,請確保業務允許數據存在可能的不一致。

復制集架構

最基礎的復制集架構是由三個成員組成的,這樣的架構為復制集提供了冗余與故障切換的余地。根據應用的需求來設計復制集的架構,盡量避免不必要的復雜化。大體遵循的策略如下:

1)決定復制集的成員個數

復制集應含有奇數個成員:奇數個成員的存在確保了復制集可以正常的選舉出主節點,如果復制集現有偶數個成員,那麽請增加一個投票節點以保證其成員個數為奇數。投票節點由於不包含復制集的數據集副本故所需資源也很少。所以我們可以將投票節點設置在其他應用的機器或是某個共享功能的機器上。

故障容錯的考量:對於復制集來說,其故障容錯就是要保證在主節點不可用的時候,剩余的節點能夠順利的選舉出新的主節點。換句話說,就是為了保證可以正常的選舉出新的主節點,需要保證復制集中多數成員的存活。復制集在沒有主節點時將無法接受寫請求,復制集的故障容錯受到其含有的成員個數的影響,但是該影響也不是直接體現的。請參考下表:

技術分享圖片

2)為特殊需求使用隱藏節點或延時節點

新增“隱藏節點”來為特殊需求提供服務,比如備份或是報表。新增“延時節點”用來保證數據的安全性,比如在主庫誤操作後,但是操作命令在延時節點還沒有執行,這時就可以通過延時節點來恢復數據。

3)以讀為主的架構的負載均衡

若業務帶來的大量的讀請求,我們可以通過做讀寫分離來提升復制集的讀能力。隨著業務的擴展,我們可以通過在其他數據中心新增從節點的方式來提高冗余能力與可用性。但為了能夠選舉出主節點,請保證復制集中多數節點的可用性。

4)通過journaling功能來在意外掉電中保護數據

我們可以通過開啟journaling功能個來在服務意外關閉或是掉電時保護數據。如果沒有開啟journaling功能,MongoDB將無法在服務意外關閉或是掉電後恢復數據,默認通過journaling是可以恢復60內的數據,因為mongodb默認60秒刷一次盤。

幾種常見架構模式

1)一個主節點與兩個從節點

包含三個帶有數據集的節點組成的復制集擁有:

l 一個主節點。

l 兩個從節點,這兩個從節點都可以在選舉中升職為主節點。

技術分享圖片

這樣的架構中除了主節點外還一直擁有兩個包含完整數據集的從節點,這樣架構的復制集提供了高可用性 與故障容災的功能。一旦主節點不可用了,復制集會將一個從節點選舉為新的主節點來繼續對外服務。之前的主節點將在其可用後再次加入復制集中。

技術分享圖片

2)一個主節點一個從節點和一個投票節點

含三個節點其中兩個帶有數據集的復制集擁有:

l 一個主節點。

l 一個從節點,這個從節點可以在選舉中升職為主節點。

l 一個投票節點,投票節點僅在選舉中進行投票。

技術分享圖片

由於投票節點不包含數據集,所以這樣的復制集架構僅有一份數據集的備份,投票節點需要的資源很少。但是,在擁有一個主節點,一個從節點和一個投票節點的復制集架構中,如果主節點或者從節點不可用了,復制集還是可以正常提供服務的。如果主節點不可用了,那麽復制集會將從節點升職為主節點。

技術分享圖片

3)擁有4個或更多節點的復制集

雖然復制集默認配置是三個節點,但是我們也可以使用擁有更高擴展性的架構,設置更多節點。新增復制集節點來提高復制集的容災能力或是提高分布式讀的讀性能。復制集需要有奇數個參與投票的節點,如果復制集中參與投票的節點是偶數個,新增一個投票節點來使復制集中參與投票的節點變為奇數。一個復制集最多能有12個節點,但是其中僅有7個參與投票的節點。

在下述這樣擁有9個節點的復制集中,有7個參與投票的節點和2個不參與投票的幾點。

技術分享圖片

4)異地分布式架構的復制集

在多個數據中心建立復制集節點可以提高數據冗余小也可以在主數據中心不可用時提供很好的故障容忍性。在其他數據中心中得復制集節點應該將優先級設置為0來避免其升職為主節點。

異地分布式架構的復制集應該擁有:

l 一個主節點在主數據中心。

l 一個從節點在主數據中心,這個節點需隨時準備成為新的主節點。

l 一個優先級為0的節點在另一個數據中心,這個節點將不能升職為主節點。

在下面這樣的復制集中,主節點和一個從節點在數據中心1 中, 數據中心2 中有一個不能升職為主節點的優先級為0的從節點。

技術分享圖片

當主節點不可用時,復制集將會選舉出一個在數據中心1的新的主節點。如果2個數據中心之間無法溝通,數據中心2中的節點將不能升職為主節點。

如果數據中心1變得不可用,您可以手動恢復從數據中心2的數據集,以最少的停機時間。

為了實現選舉,主數據中心上應該有多數節點。同時也別忘了讓復制集保持奇數個節點。當我們在其他數據中心新增節點而導致復制集擁有偶數個節點的時候,應該新建一個投票節點。

MongoDB復制集成員及架構介紹(一)