MongoDB 複製機制

pursuer.chen發表於2018-03-23

一、複製原理

MongoDB的複製功能是使用操作日誌oplog實現的,oplog包含主節點(Master)的每一次寫操作,oplog是local本地資料庫中的一個資料集合,其它非主節點(Secondary)通過讀取主節點的oplog集合中的記錄同步到對應的集合,然後再寫入到自身的local資料庫的oplog集合中。每個節點都維護著自己的oplog,記錄著每一次從主節點複製資料的操作。這樣每個成員都可以作為同步源提供給其它成員使用。

注意:需要注意Secondary節點同步資料的順序是先同步資料,然後再寫入oplog;這點和mysql的機制不同。但是每個節點oplog中記錄的同步資料是完全一致的,所以也不擔心被執行多次。

 

二、oplog集合

1.insert操作

/* 1 */

{

    "ts" : Timestamp(1520580648, 1),
    "t" : NumberLong(20),
    "h" : NumberLong(-8701728013874689868),
    "v" : 2,
    "op" : "i",
    "ns" : "test.person",
    "ui" : UUID("782befd9-80ae-4a2c-86ae-33a147e7c948"),
    "wall" : ISODate("2018-03-09T07:30:48.120Z"),
    "o" : {
        "_id" : ObjectId("5aa2382f7239a98c7e679114"),
        "name" : "zhang"
    }
}

2.update操作

/* 1 */

{
    "ts" : Timestamp(1520584444, 2),
    "t" : NumberLong(20),
    "h" : NumberLong(7151217369265341585),
    "v" : 2,
    "op" : "u",
    "ns" : "test.person",
    "ui" : UUID("782befd9-80ae-4a2c-86ae-33a147e7c948"),
    "o2" : {
        "_id" : ObjectId("5aa2382f7239a98c7e679114")
    },
    "wall" : ISODate("2018-03-09T08:34:04.777Z"),
    "o" : {
        "$v" : 1,
        "$set" : {
            "name" : "wang"
        }
    }
}
  • ts: 操作時間,當前timestamp + 計數器,計數器每秒都被重置
  • h:操作的全域性唯一標識
  • v:oplog版本資訊
  • op:操作型別:
  1. i:插入操作
  2. u:更新操作
  3. d:刪除操作
  4. c:執行命令(如createDatabase,dropDatabase)
  5. n:空操作,特殊用途
  • ns:操作針對的集合
  • ui:
  • o:操作內容,如果是更新操作
  • o2:操作查詢條件,僅update操作包含該欄位
  • wall:記錄的時間戳。

3.查詢oplog集合

db.oplog.rs.find(

{"op":{$in:["i","u","d"]}}

)

.sort({"wall":-1});

三、初始化同步

1.選擇一個成員作為同步源,在local.me中建立識別符號;刪除已存在的資料庫。

2.將同步源的所有資料複製到本地。所有的操作都被集合到oplog中。

3.將第一個oplog同步中的操作記錄下來。

4.建立相關索引,如果集合比較大該過程可能會花費很長的時間。

5.將建立索引過程中同步源增加的記錄同步過來。

6.同步完成,修改節點狀態為SECONDARY

四、心跳

每個成員每隔兩秒鐘就會向其它成員傳送一個心跳請求,心跳的請求資訊量非常的小,用於檢查每個成員的狀態。

心跳最主要的功能之一就是讓主節點知道自己是否滿足集合“大多數”的條件。如果主節點不再得到“大多數”伺服器的支援,它就會退位變成備份節點。

成員狀態

Number

Name

State Description

0

STARTUP

Not yet an active member of any set. All members start up in this state. The mongod parses the replica set configuration document while inSTARTUP.

1

PRIMARY

The member in state primary is the only member that can accept write operations. Eligible to vote.

2

SECONDARY

A member in state secondary is replicating the data store. Eligible to vote.

3

RECOVERING

Members either perform startup self-checks, or transition from completing a rollback or resync. Eligible to vote.

5

STARTUP2

The member has joined the set and is running an initial sync.

6

UNKNOWN

The member’s state, as seen from another member of the set, is not yet known.

7

ARBITER

Arbiters do not replicate data and exist solely to participate in elections.

8

DOWN

The member, as seen from another member of the set, is unreachable.

9

ROLLBACK

This member is actively performing a rollback. Data is not available for reads.

10

REMOVED

This member was once in a replica set but was subsequently removed.

五、選舉

當一個成員無法到達主節點時,它就會申請被選舉為主節點。希望被選舉為主節點的成員會向它能到達的所有成員傳送通知。如果這個成員不符合候選人的要求,其它成員可能會知道相關原因:這個成員的資料落後於副本集,或者已經有一個執行中的主節點(希望被選舉為主節點的成員無法到達這個主節點)。在這些情況下,其它成員不會允許進行選舉。

如果沒有其它成員反對,其他成員就會對這個成員進行選舉投票,如果滿足副本集中“大多數”贊成票,它就被選舉成功,轉換成為主節點。否則選舉失敗仍然處於備份節點狀態,之後還可以再次申請被選舉為主節點。而主節點會一直主節點狀態,除非它由於不再滿足“大多數”的要求或者當機而退位,另外副本集被重新配置也會導致主節點退位。

在網路良好的情況下,同時投票伺服器也正常執行那麼選舉過程會很快,由於節點之間的互ping是每隔2S,所以如果有主節點不可用那麼2S之內就會有成員發現,然後就會立即開始選舉,整個過程正常只會花費幾毫秒。如果存在網路問題或者伺服器過載響應緩慢都有可能觸發選舉。在這種情況下,心跳會在最多10S之後超時。如果選舉打成平局,每個成員都需要等待30S才能開始下一次選舉,所以如果發生太多錯誤的情況下選舉可能會花費幾分鐘的時間。

六、回滾

 

一般情況下跨資料中心複製要比同資料中心複製慢。

上圖的兩個資料中心之間出現網路故障,DC1最後的操作是126,DC2最後的操作是125;DC1的126操作還沒有被複制到DC2;由於採取的是多數節點的投票機制,DC2資料中心的副本滿足“大多數”節點的要求(一共5臺伺服器,3臺伺服器即可超過半數投票)。因此其中一臺伺服器會被選舉成為新的主節點,這個主節點會繼續後續的寫操作。假設在DC1的網路恢復之前DC2已經操作到了130。

DC1

123

124

125

126

DC2

123

124

125

126''

127''

128''

129''

130''

 

在DC1網路恢復之後,DC1就會從DC2同步126之後的操作,但是會發現這個操作是無法操作的,這時候DC1和DC2就會進入回滾過程,DC1和DC2會查詢到二者共同的操作點125,DC1和DC2都會回滾到125,然後二者才會繼續後面的同步操作

注意:如果回滾的資料量比較大需要很長的時間,這時可能會導致回滾失敗,對於回滾失敗的節點,必須要重新進行同步。一般造成這種情況的主要原因是備份節點遠遠落後於主節點,而這時主節點掛了。

 

 

 

 

 

 

 

 

備註:

    作者:pursuer.chen

    部落格:http://www.cnblogs.com/chenmh

本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須註明文章來源,且在文章開頭明顯處給明連結,否則保留追究責任的權利。

《歡迎交流討論》

 

相關文章