mongoDB研究筆記:復制集數據同步機制


   http://www.cnblogs.com/guoyuanwei/p/3279572.html  概述了復制集,整體上對復制集有了個概念,但是復制集最重要的功能之一數據同步是如何實現的?帶着這個問題,下面展開分析。

先利用mongo客戶端登錄到復制集的primary節點上。

>mongo --port 40000

查看實例上所有數據庫

rs0:PRIMARY> show dbs

local   0.09375GB

可以看到只有一個local數據庫,因為此時還沒有在復制集上創建任何其它數據庫,local數據庫為復制集所有成員節點上默認創建的一個數據庫。在primary節點上查看local數據上的集合:

rs0:PRIMARY> show collections

oplog.rs

slaves

startup_log

system.indexes

system.replset

如果是在secondary節點則local數據庫上的集合與上面有點不同,secondary節點上沒有slaves集合,因為這個集合保存的是需要從primary節點同步數據的secondary節點;secondary節點上會有一個me集合,保存了實例本身所在的服務器名稱;secondary節點上還有一個minvalid集合,用於保存對數據庫的最新操作的時間截。其它集合primary節點和secondary節點都有,其中startup_log集合表示的是mongod實例每一次的啟動信息;system.indexes集合保存的是當前數據庫(local)上的所有索引信息;system.replset集合保存的是復制集的成員配置信息,復制集上的命令rs.conf()實際上是從這個集合取的數據返回的。最后要介紹的集合是oplog.rs,這個可是重中之中。

mongoDB就是通過oplog.rs來實現復制集間數據同步的,為了分析數據的變化,先在復制集上的primary節點上創建一個數據庫students,然后插入一條記錄。

rs0:PRIMARY> use students

switched to db students

rs0:PRIMARY> db.scores.insert({"stuid":1,"subject":"math","score":99});

接着查看一下primary節點上oplog.rs集合的內容:

rs0:PRIMARY> use local

switched to db local

rs0:PRIMARY> db.oplog.rs.find();

返回記錄中會多出一條下面這樣的記錄(里面還有幾條記錄是復制集初始化時創建的):

{ "ts" : { "t" : 1376838296, "i" : 1 }, "h" : NumberLong("6357586994520331181"),

 "v" : 2, "op" : "i", "ns" : "students.scores", "o" : { "_id" : ObjectId("5210e2

98d7b419b44afa58cc"), "stuid" : 1, "subject" : "math", "score" : 99 } }

里面有幾個重要字段,其中"ts"表示是這條記錄的時間截,"t"是秒數,"i"每秒操作的次數;字段"op"表示的是操作碼,值為"i"表示的是insert操作;"ns"表示插入操作發生的命名空間,這里值為: "students.scores",由數據庫和集合名構成;"o"表示的是此插入操作包含的文檔對象;

當primary節點完成插入操作后,secondary節點為了保證數據的同步也會完成一些動作:

所有secondary節點檢查自己的local數據上oplog.rs集合,找出最近的一條記錄的時間截;接着它會查詢primary節點上的oplog.rs集合,找出所有大於此時間截的記錄;最后它將這些找到的記錄插入到自己的oplog.rs集合中並執行這些記錄所代表的操作;通過這三步策略,就能保證secondary節點上的數據與primary節點上的數據同步了。

查看一下secondary節點上的數據,證明上面的分析是正確的。

rs0:SECONDARY> show dbs

local   0.09375GB

students        0.0625GB

  在secondary節點上新插入了一個數據庫students。但是有一點要注意:現在還不能在secondary節點上直接查詢students集合上的內容,默認情況下mongoDB的所有讀寫操作都是在primary節點上完成的,后面也會介紹通過設置從secondary節點上來讀,這將引入一個新的主題,后面再分析。

關於oplog.rs集合還有一個很重要的方面,那就是它的大小是固定的,mongoDB這樣設置也是有道理的,假如大小沒限制,那么隨着時間的推移,在數據庫上的操作會逐漸累積,oplog.rs集合中保存的記錄也會逐漸增多,這樣會消耗大量的存儲空間,同時對於某個時間點以前的操作記錄,早已同步到secondary節點上,也沒有必要一直保存這些記錄,因此mongoDB將oplog.rs集合設置成一個capped類型的集合,實際上就是一個循環使用的緩沖區。

固定大小的oplog.rs會帶來新的問題,考慮下面這種場景:假如一個secondary節點因為宕機,長時間不能恢復,而此時大量的寫操作發生在primary節點上,當secondary節點恢復時,利用自己oplog.rs集合上最新的時間截去查找primary節點上的oplog.rs集合,會出現找不到任何記錄。因為長時間不在線,primary節點上的oplog.rs集合中的記錄早已全部刷新了一遍,這樣就不得不手動重新同步數據了。因此oplog.rs的大小是很重要,在32位的系統上默認大小是50MB,在64位的機器上默認是5%的空閑磁盤空間大小,也可以在mongod啟動命令中通過項—oplogSize設置其大小。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM