1. 程式人生 > >MongoDB副本集其他細節

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

如下:

p254

備份節點通過查詢這個集合就知道要複製哪些資料,同時,每一個備份節點也都維護著自己的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版》

更多資料請關注公眾號:

在這裡插入圖片描述