MongoDB 复制机制
一、復(fù)制原理
MongoDB的復(fù)制功能是使用操作日志oplog實現(xiàn)的,oplog包含主節(jié)點(Master)的每一次寫操作,oplog是local本地數(shù)據(jù)庫中的一個數(shù)據(jù)集合,其它非主節(jié)點(Secondary)通過讀取主節(jié)點的oplog集合中的記錄同步到對應(yīng)的集合,然后再寫入到自身的local數(shù)據(jù)庫的oplog集合中。每個節(jié)點都維護著自己的oplog,記錄著每一次從主節(jié)點復(fù)制數(shù)據(jù)的操作。這樣每個成員都可以作為同步源提供給其它成員使用。
注意:需要注意Secondary節(jié)點同步數(shù)據(jù)的順序是先同步數(shù)據(jù),然后再寫入oplog;這點和mysql的機制不同。但是每個節(jié)點oplog中記錄的同步數(shù)據(jù)是完全一致的,所以也不擔心被執(zhí)行多次。
?
二、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 + 計數(shù)器,計數(shù)器每秒都被重置
- h:操作的全局唯一標識
- v:oplog版本信息
- op:操作類型:
- ns:操作針對的集合
- ui:
- o:操作內(nèi)容,如果是更新操作
- o2:操作查詢條件,僅update操作包含該字段
- wall:記錄的時間戳。
3.查詢oplog集合
db.oplog.rs.find({"op":{$in:["i","u","d"]}}).sort({"wall":-1});三、初始化同步
1.選擇一個成員作為同步源,在local.me中創(chuàng)建標識符;刪除已存在的數(shù)據(jù)庫。
2.將同步源的所有數(shù)據(jù)復(fù)制到本地。所有的操作都被集合到oplog中。
3.將第一個oplog同步中的操作記錄下來。
4.創(chuàng)建相關(guān)索引,如果集合比較大該過程可能會花費很長的時間。
5.將創(chuàng)建索引過程中同步源增加的記錄同步過來。
6.同步完成,修改節(jié)點狀態(tài)為SECONDARY
四、心跳
每個成員每隔兩秒鐘就會向其它成員發(fā)送一個心跳請求,心跳的請求信息量非常的小,用于檢查每個成員的狀態(tài)。
心跳最主要的功能之一就是讓主節(jié)點知道自己是否滿足集合“大多數(shù)”的條件。如果主節(jié)點不再得到“大多數(shù)”服務(wù)器的支持,它就會退位變成備份節(jié)點。
成員狀態(tài)
| 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. |
五、選舉
當一個成員無法到達主節(jié)點時,它就會申請被選舉為主節(jié)點。希望被選舉為主節(jié)點的成員會向它能到達的所有成員發(fā)送通知。如果這個成員不符合候選人的要求,其它成員可能會知道相關(guān)原因:這個成員的數(shù)據(jù)落后于副本集,或者已經(jīng)有一個運行中的主節(jié)點(希望被選舉為主節(jié)點的成員無法到達這個主節(jié)點)。在這些情況下,其它成員不會允許進行選舉。
如果沒有其它成員反對,其他成員就會對這個成員進行選舉投票,如果滿足副本集中“大多數(shù)”贊成票,它就被選舉成功,轉(zhuǎn)換成為主節(jié)點。否則選舉失敗仍然處于備份節(jié)點狀態(tài),之后還可以再次申請被選舉為主節(jié)點。而主節(jié)點會一直主節(jié)點狀態(tài),除非它由于不再滿足“大多數(shù)”的要求或者宕機而退位,另外副本集被重新配置也會導(dǎo)致主節(jié)點退位。
在網(wǎng)絡(luò)良好的情況下,同時投票服務(wù)器也正常運行那么選舉過程會很快,由于節(jié)點之間的互ping是每隔2S,所以如果有主節(jié)點不可用那么2S之內(nèi)就會有成員發(fā)現(xiàn),然后就會立即開始選舉,整個過程正常只會花費幾毫秒。如果存在網(wǎng)絡(luò)問題或者服務(wù)器過載響應(yīng)緩慢都有可能觸發(fā)選舉。在這種情況下,心跳會在最多10S之后超時。如果選舉打成平局,每個成員都需要等待30S才能開始下一次選舉,所以如果發(fā)生太多錯誤的情況下選舉可能會花費幾分鐘的時間。
六、回滾
?
一般情況下跨數(shù)據(jù)中心復(fù)制要比同數(shù)據(jù)中心復(fù)制慢。
上圖的兩個數(shù)據(jù)中心之間出現(xiàn)網(wǎng)絡(luò)故障,DC1最后的操作是126,DC2最后的操作是125;DC1的126操作還沒有被復(fù)制到DC2;由于采取的是多數(shù)節(jié)點的投票機制,DC2數(shù)據(jù)中心的副本滿足“大多數(shù)”節(jié)點的要求(一共5臺服務(wù)器,3臺服務(wù)器即可超過半數(shù)投票)。因此其中一臺服務(wù)器會被選舉成為新的主節(jié)點,這個主節(jié)點會繼續(xù)后續(xù)的寫操作。假設(shè)在DC1的網(wǎng)絡(luò)恢復(fù)之前DC2已經(jīng)操作到了130。
DC1
| 123 | 124 | 125 | 126 |
DC2
| 123 | 124 | 125 | 126'' | 127'' | 128'' | 129'' | 130'' |
?
在DC1網(wǎng)絡(luò)恢復(fù)之后,DC1就會從DC2同步126之后的操作,但是會發(fā)現(xiàn)這個操作是無法操作的,這時候DC1和DC2就會進入回滾過程,DC1和DC2會查找到二者共同的操作點125,DC1和DC2都會回滾到125,然后二者才會繼續(xù)后面的同步操作
注意:如果回滾的數(shù)據(jù)量比較大需要很長的時間,這時可能會導(dǎo)致回滾失敗,對于回滾失敗的節(jié)點,必須要重新進行同步。一般造成這種情況的主要原因是備份節(jié)點遠遠落后于主節(jié)點,而這時主節(jié)點掛了。
?
?
?
?
?
?
?
?
| 備注: ??? 作者:pursuer.chen ??? 博客:http://www.cnblogs.com/chenmh 本站點所有隨筆都是原創(chuàng),歡迎大家轉(zhuǎn)載;但轉(zhuǎn)載時必須注明文章來源,且在文章開頭明顯處給明鏈接,否則保留追究責任的權(quán)利。 《歡迎交流討論》 |
?
總結(jié)
以上是生活随笔為你收集整理的MongoDB 复制机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在 Scale Up 中使用 Healt
- 下一篇: 吃自助餐怎么样一个顺序吃法才合算?