MongoDB副本集其他細節
副本集環境的搭建以及一些基本的操作我們都瞭解了,本文我們來看看這個資料複製到底是怎麼實現的。
本文是MongoDB系列的第十七篇文章,瞭解前面的文章有助於更好的理解本文:
1.Linux上安裝MongoDB
2.MongoDB基本操作
3.MongoDB資料型別
4.MongoDB文件更新操作
5.MongoDB文件查詢操作(一)
6.MongoDB文件查詢操作(二)
7.MongoDB文件查詢操作(三)
8.MongoDB檢視執行計劃
9.初識MongoDB中的索引
10.MongoDB中各種型別的索引
11.MongoDB固定集合
12.MongoDB管道操作符(一)
13.MongoDB管道操作符(二)
14.MongoDB中MapReduce使用
15.MongoDB副本集搭建
16.MongoDB副本集配置
資料同步方式
MongoDB中的複製功能主要是使用操作日誌oplog.rs來實現的,oplog.rs包含了主節點的每一次寫操作,oplog.rs是主節點中local資料庫的一個固定集合,我們可以通過如下命令檢視到:
use local
show tables
如下:
備份節點通過查詢這個集合就知道要複製哪些資料,同時,每一個備份節點也都維護著自己的oplog.rs,自己的oplog.rs則用來記錄每一次從主節點複製資料的操作,如此,每一個備份節點都可以再作為資料來源提供給其他成員使用,如果某一個備份節點在使用的過程中掛掉了,那麼當它重啟之後,會自動從oplog.rs的最後一個操作開始同步。
上文我們也已經說過oplog.rs是一個固定集合,我們可以通過db.getCollection('oplog.rs').stats()
這個命令來檢視這個固定集合的屬性,包括集合大小等,執行部分結果如下:
{ "ns" : "local.oplog.rs", "size" : 18170305, "count" : 177443, "avgObjSize" : 102, "storageSize" : 5902336, "capped" : true, "max" : -1, "maxSize" : 1038090240, "sleepCount" : 0, "sleepMS" : 0, }
既然是固定集合,它裡邊能夠儲存的資料大小就是有限的。通常,oplog.rs使用空間的增長速度與系統處理處理寫請求的速率近乎相同,比如主節點每分鐘處理了1KB的寫入請求,那麼oplog.rs也可能會在一分鐘內寫入1KB條操作日誌,但是如果主節點執行了批量刪除的命令,比如下面這種:
db.c1.deleteMany({x:{$type:1}})
此時每一個受影響的文件都會產生一條oplog中的日誌,這個時候oplog.rs中的日誌會快速增加。
成員狀態
到目前為止我們瞭解到的成員狀態有兩種,一個是PRIMARY,還有一個是SECONDDARY,成員狀態的獲取需要靠心跳來維護,副本集中的每一個成員每隔兩秒就會向其他成員傳送一個心跳請求,用來檢查成員的狀態,成員的狀態主要有如下幾種:
STARTUP
副本集中的成員剛剛啟動時處於這個狀態下,此時,MongoDB會去載入成員的副本集配置,配置載入成功之後,就進入到STARTUP2的狀態。
STARTUP2
整個初始化同步過程都處於這個狀態。
RECOVERING
這個狀態是由STARTUP2狀態來的,此時成員運轉正常,但是此時還不能處理讀取請求。
ARBITER
這是仲裁者所處的狀態。
DOWN
當一個原本執行正常的成員無法訪問到時,該成員就處於DOWN的狀態。
UNKNOWN
如果一個成員無法到達其他任何成員,該成員就處於UNKNOWN狀態,比如我們利用rs.add()方法新增一個不存在的成員,這個成員的狀態就是UNKNOWN。
REMOVED
成員被從副本集中移除時就變成這個狀態。
ROLLBACK
如果成員正在進行資料回滾,它就處於ROLLBACK狀態,回滾結束後會轉換為RECOVERING狀態。
FATAL
當一個成員發生了不可挽回的錯誤時,且不再嘗試恢復正常的話,就處於這個狀態。
主節點轉備份節點
通過如下命令可以讓主節點轉為備份節點:
rs.stepDown()
主節點轉為備份節點之後會有新的主節點被選舉出來,可以通過rs.status()來檢視新的主節點。
rs.status()方法
前面我們已經多次使用過rs.status()方法,rs.status()方法會列出每個備份節點的含義,我們來看看這些引數的含義,先來列出一個rs.status()方法的返回值樣例:
{
"members" : [
{
"_id" : 1,
"name" : "192.168.248.135:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 241,
"optime" : {
"ts" : Timestamp(1509881297, 1),
"t" : NumberLong(16)
},
"optimeDurable" : {
"ts" : Timestamp(1509881297, 1),
"t" : NumberLong(16)
},
"optimeDate" : ISODate("2017-11-05T11:28:17Z"),
"optimeDurableDate" : ISODate("2017-11-05T11:28:17Z"),
"lastHeartbeat" : ISODate("2017-11-05T11:28:18.073Z"),
"lastHeartbeatRecv" : ISODate("2017-11-05T11:28:18.769Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.248.136:27017",
"configVersion" : 15
},
{
"_id" : 3,
"name" : "192.168.248.136:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 250,
"optime" : {
"ts" : Timestamp(1509881297, 1),
"t" : NumberLong(16)
},
"optimeDate" : ISODate("2017-11-05T11:28:17Z"),
"electionTime" : Timestamp(1509881276, 1),
"electionDate" : ISODate("2017-11-05T11:27:56Z"),
"configVersion" : 15,
"self" : true
}
]
}
1.stateStr用來描述當前節點的狀態。
2.uptime表示從成員可達到現在所經歷的時間。
3.optimeDate表示每個成員的oplog中最後一個操作發生的時間。
4.lastHeartbeat表示當前伺服器最後一次收到其他成員心跳的時間。
5.pingMs表示心跳從當前伺服器到達某個成員所花費的平均時間。
6.syncingTo表示同步的資料來源。
7.health表示該伺服器是否可達,1表示可達,0表示不可達。
複製鏈問題
資料複製時可以從主節點直接複製,也可以從備份節點開始複製,從備份節點複製可以形成複製鏈,如果想禁止複製鏈,即所有的資料都從主節點複製,可以通過chainingAllowed屬性來設定,具體步驟如下:
config=rs.config()
config.settings.chainingAllowed=false
rs.reconfig(config)
好了,MongoDB中副本集的其他細節我們就先說到這裡,小夥伴們有問題歡迎留言討論。
參考資料:
1.《MongoDB權威指南第2版》
更多資料請關注公眾號: