MongoDB之複製集(一)原理篇,mongodb複製原理篇

來源:互聯網
上載者:User

MongoDB之複製集(一)原理篇,mongodb複製原理篇

參考資料

官網:www.mongodb.org

中文社區:www.mongoing.com

線上教程:https://university.mongodb.com/

  mongodb支援傳統的master-slave架構。沒有自動容錯移轉功能,需要指定master和slave端。建議使用複製集架構,複製集架構比複製架構更好維護,功能更強。

一、基本概念

複製集是由一組擁有相同資料集的 mongod 執行個體組成的。其中的一個節點為主節點(Primary),所有的寫請求都是在它上面完成的。而其他的節點都是從節點(secondary),從節點接收從主節點上傳來的操作並應用,並以此來保證其與主節點的資料集一致。

主節點:接收所有來自用戶端的寫操作。一個複製集只能有一個主節點。由於在一個複製集中只有一個成員能夠接收寫操作,複製集為所有來自主節點的讀提供了 嚴格的一致性校正 。主節點通過將所有資料集的變動記錄到 oplog 中以支援複製的實現

從節點:將主節點上的oplog複製過來並應用這些操作來修改其自己的資料集以確保從節點的資料集與主節點的資料集一致。一旦主節點不可用了,複製集就會將一個從節點選舉成為新的主節點。用戶端預設是從主節點進行讀操作,但是用戶端也可以通過指定 複製集讀選項 來將讀操作發送給從節點。需要注意的是,在從節點上進行讀操作時,所獲得的資料可能不是此時主節點上的值。

投票節點:我們也可以為複製集新增一個額外的 mongod 執行個體作為 投票節點 。該節點中並不包含資料集,投票節點的作用僅僅是在選舉過程中參與投票。當複製集的成員個數為偶數時,添加一個投票節點可以防止平局的出現,通過多數選票來選舉出新的主節點。由於投票節點僅提供投票功能,故無需一個專用的物理機。

投票節點將只做投票使用。當主節點降職變為從節點的時候,其他的一個從節點將在選舉中被推選為主節點。

二、複製集架構

最基礎的複製集架構是由三個成員組成的。這樣的架構為複製集提供了冗餘與故障切換的餘地。根據應用的需求來設計複製集的架構,盡量避免不必要的複雜化。

複製集應含有奇數個成員

  奇數個成員的存在確保了複製集可以正常的選舉出主節點。如果複本集現有偶數個成員,那麼請增加一個投票節點以保證其成員個數為奇數。

為特殊需求使用隱藏節點和延時節點

  新增隱藏節點或是延時節點來為特殊需求提供服務,比如備份或是報表。

以讀為主的架構的負載平衡

  若業務帶來的大量的讀請求,我們可以通過做讀寫分離來提升複製集的讀能力。隨著業務的擴充,我們可以通過在其他資料中心新增從節點的方式來提高冗餘能力與可用性。

決定複製集各成員的分布與功能

物理位置上的節點分布

  在其他資料中心擁有至少一個複製集節點可以很好地在主要資料中心出問題時為資料提供安全性保障。將這類節點的priority設定為0,以防其升職為主節點。

保證在一個資料中心中擁有多數節點

  當複製集在多個資料中心擁有節點,且各資料中心網路隔離時,為了保證資料的複製與傳輸,各節點之間需要能夠正常溝通。

在選舉中,各節點需要能夠互相溝通來保證其多數性。為了保證複製集節點能夠保持多數且能夠正常的選舉出主節點,我們需要保證一個資料中心擁有複製集中的多數節點。

三、故障切換

複製集通過選舉來從當前主節點停用困境中恢複。

複製集選舉

一旦當前主節點不可用了,複製集就會進行選舉並推選出一個新的主節點。

故障切換時的復原

之前的主節點在故障切換後重新迴歸複製集時將會發生寫操作的復原。復原只會發生在主節點的寫操作沒能成功在從節點上應用就辭職的情況下。當主節點重新以一個從節點加入複製集,它將進行 “復原”,其上得寫操作將與複製集中其他成員的保持一致。

MongoDB會盡量避免復原的發生。復原如果確實發生了,往往是由於網路導致的。從節點如果無法跟上之前主節點上的寫操作的吞吐,那麼將會加劇復原的影響範圍。

當主節點在從節點完成寫操作的複製後才辭職的或是主節點一直是可用的或是與多數節點可以溝通的,將不會發生復原。

選取復原的資料

當復原發生後,管理員需要決定是恢複復原的資料還是忽視它。MongoDB將復原的資料以 BSON 檔案的形式寫到資料庫 dbPath 檔案夾中的 rollback/ 目錄。復原資料檔案的命名是按照以下規則進行的

<database>.<collection>.<timestamp>.bson

如:records.accounts.2011-05-09T18-10-04.0.bson

可通過設定 複製集的安全寫層級 確保寫操作應用到了整個複製集來避免復原。

影響選舉的因素

1.心跳檢測

複製整合員每兩秒向複製集中其他成員進行心跳檢測。如果某個節點在10秒內沒有返回,那麼它將被標記為不可用。

2.串連

   如果複製集中的某個節點不能串連上其他多數節點,那麼它將不能升職為主節點。在選舉中,多數是指多數投票而不是多數節點個數。如果複製集是由三個節點群組成的,且三個節點均可投票,只要其中兩個節點能夠互相溝通那麼複製集就能選舉出新的主節點。如果有兩個節點不可用了,那麼剩下的節點將為從節點,因為它不能與複製集中多數節點進行溝通。 如果兩個從節點不可用了,剩下的主節點將降職為從節點。

3.網路隔離

    網路隔離影響了選舉中多數選票的結構。如果主節點不可用了,且每個相互隔離的網路中都沒有多數選票的出現,那麼複製集將 不會選舉出新的主節點。複製集將變為唯讀。為了避免這種情況的出現,我們需要將多數節點置於主要資料中心,少數節點放於其他資料中心。


觸發選舉的情況

當複製集中沒有主節點可用的時候將觸發選舉,比如:

1.新複製集的初始化。

2.一個從節點無法與主節點進行串連。當從節點們無法與主節點進行溝通的時候將會觸發選舉。

3.主節點辭職了

主節點將在以下幾種情況下辭職:

1.在接收到 replSetStepDown 命令後。

2.現有的某個從節點在選舉中合格,且它又有更高的優先順序。

3.當主節點無法與複製集中多數節點進行溝通的時候。

4.有些情況下,在我們需要修改一些複製集配置的時候會觸發選舉,導致主節點辭職

注意:當主節點辭職後,它將關閉所有已經建立的串連來確保用戶端不會在從節點中進行寫操作。這將對用戶端對複製集的架構擷取與防止復原提供協助。

我們具體來看下選舉的過程

心跳檢測

        假設我們有三個節點的replica sets:a、b、c。在replica sets結構中,這三個節點每2秒會各自向其它兩個節點發送一個心跳檢測請求。比如a節點向b和c節點各發送了一個心跳檢測請求;正常情況下,b、c會返回一個包含自身資訊的回複包,回複包中主要包括的資訊:它們現在是什麼角色(primary 還是 secondary),他們是否能夠在必要的時候成為 primary,以及他們當前時鐘時間等等。

a節點在收到回複包後,會用這些資訊更新自己的一個狀態映射表,更新的內容包括:是否有新的節點加入或有老的節點宕掉,這個請求的網路傳輸時間等等。

而當a節點的映射表發生了變化,那a會進行下面的邏輯判斷:如果a是 primary,而另外一個節點出現故障,那麼它會查看自己是否還能和叢集中大多數節點進行通訊,如果不能與大多數節點通訊,他會把自己從 primary 降級為 secondary。(在replica sets中,primary 必須能夠和叢集中的大多數節點進行通訊,以免發生網路斷開形成兩個或多個節點群各自為政的情況,這樣會影響到資料的一致性)

關於降級

在 MongoDB 中,寫操作預設通過 fire-and-forget 的模式來進行,也就是說寫操作通常不關心是否成功,發完請求後用戶端就認為成功了。但如果這時候 primary 進行降級操作,那麼用戶端並不知道這時候 primary 已經降級成為 secondary 了,用戶端可能還會將後續的寫操作發送給這個節點。這時候剛剛降級的這個 secondary 可以發送一個包說“我已經不是 primary 了”,但是我們上面說過了,用戶端根本就無視你這個包。所以用戶端根本不知道這次寫入已經失敗了。

對於這個問題,MongoDB開發人員已經考慮到了,解決方案是,在一個 primary 降級成為 secondary 後,它會將原來的所有串連關閉。這樣用戶端在下一次寫入的時候就會出現 socket 錯誤。而用戶端在發現這個錯誤之後,就會重新向叢集擷取新的 primary的地址,並將後續的寫操作都往新的伺服器上寫入。

選舉

再來看心跳監測請求:如果a是一個 secondary,那麼a會定時檢測是否需要選舉自己成為 primary。其檢測內容包括:

1.是否叢集中有其它節點認為自己是 primary?

2.a節點自己是否已經是 primary?

3.a節點自己是否有資格成為 primary?

如果這三個問題中的任何一個回答是肯定的,那麼a節點就不會試圖把自己變成primary。(即:只有當a節點是一個能夠當 primary 的secondary,並且其它節點都不是primary時,a才會發起選舉並選自己為primary)

而當a發現現在需要一個 primary 並且自己又正好可以充當時,它就會發起一輪選舉:a節點會向b、c節點各發起一個請求包,告知他們”我認為我可以接管 primary 的角色,你們覺得怎麼樣?“

當b和c收到上面的請求包時,他們會進行下面幾項檢測:

1.他們是否已經支援叢集中有一個primary了?

2.他們自己的資料是否比a節點更新?

3.是否有其它節點的資料比a節點更新?

如果上麵條件有任何一個滿足,那麼他們都會認為a不夠資格成為 primary,他們會發送一個返回包告知a說”停止選舉!“。而如果三個條件都不成立,也就是說他們認為目前叢集中確實沒有 primary,並且a的資料又是最新的,那麼他們會發送返回包告知a說”沒問題“。

如果a收到”停止選舉!“的返回,那麼他會馬上停止選舉並保持自己為 sencondary 狀態。

如果a收到所有其它節點都返回說”沒問題“,那麼他會進入選舉過程的第二階段。

在第二階段中,a會向其它節點發送一個包,說”我宣布我已經是 primary 了“。這時候,b和c節點再進行一些最終的確認:上面的判斷過的所有條件是否依然表明a可以做 primary,如果確實如此,那麼他們會在本輪 primary 選舉中向a出贊成票。並且他們投完贊成票後,30秒內不會再做其它投票決定。

上面是說如果第二次確認還是通過的情況,那麼如果最終確認沒有通過呢。他們會投一個反對票,反對a成為 primary,如果有反對票產生,那麼這一輪選舉就失敗了。a還是保持 secondary 的身份。

假設一種情況,如果b給a投了贊成票,而c給a投了反對票。那這時候b由於投了贊成票,它在30秒內不能再進行投票。所以如果這時候c發起選舉想讓自己成為 primary,那麼c這時候必須要獲得a的贊成票。因為這時候b不能投票,為了擷取多數票,c必須獲得a的贊成票。

所以投票的規則是這樣的:如果沒有人投反對票,並且贊成票的比例過半,那麼本輪選舉對象就能夠成為 primary。


四、複製集的讀與寫

預設情況下,應用程式將直接在複製集的主節點上進行讀操作。 在主節點上進行讀操作確保了讀操作返回的資料都是最新的資料。但是,在對資料一致性要求沒那麼嚴格的情況下,如果將部分或是所有的讀操作分發到複製集的從節點上去處理,能夠提升讀的效能也能降低應用程式的等待時間。

為了確保從從節點上進行讀操作時的資料一致性,我們可以配置用戶端來確保寫操作在應用到複製集中所有節點後才算成功完成。 

MongoDB的驅動支援5種複製集讀選項。

複製集讀選項模式 詳細說明
primary 預設模式,所有的讀操作都在複製集的 主節點 進行的。
primaryPreferred 在大多數情況時,讀操作在 主節點 上進行,但是如果主節點不可用了,讀操作就會轉移到 從節點 上執行。
secondary 所有的讀操作都在複製集的 從節點 上執行。
secondaryPreferred 在大多數情況下,讀操作都是在 從節點 上進行的,但是當 從節點 不可用了,讀操作會轉移到 主節點 上進行。
nearest 讀操作會在 複製集 中網路延時最小的節點上進行,與節點類型無關。
通過配置來找到適合自己業務的架構。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.