mongoDB研究筆記:複製集概述

自我學習,僅供參考:mongodb

數據庫老是會遇到各類失敗的場景,如網絡鏈接斷開、斷電等,儘管journaling日誌功能也提供了數據恢復的功能,但journaling一般是針對單個節點來講的,只能保證單節點數據的一致性,而複製集一般是由多個節點組成,每一個節點除了journaling日誌恢復功能外,整個複製集還具備故障自動轉移的功能,這樣能保證數據庫的高可用性。在生產環境中一個複製集最少應該包含三個節點,其中有一個必須是主節點,典型的部署結構以下圖:shell

 

  

其中每一個節點都是一個mongod進程對應的實例,節點之間互相週期性的經過心跳檢查對方的狀態,默認狀況下primary節點負責數據的讀、寫,second節點備份primary節點上的數據(如何備份?下面會分析),可是arbiter節點不會從primary節點同步數據,從它的名字arbiter能夠看出,它起到的做用只是當primary節點故障時,可以參與到複製集剩下的節點中,選擇出一個新的primary節點,它本身永遠不會變爲primary節點,也不會參與數據的讀寫。也就是說,數據庫的數據會存在primary和second節點中,second節點至關於一個備份,固然second節點能夠有多個,當primary節點故障時,second節點有可能變爲primary節點。上圖是一個生產環境所需的最少節點數,下面就配置一個這樣的複製集。數據庫

(1)建立複製集中每一個節點存放數據的目錄服務器

E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_0網絡

E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_1學習

E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_2日誌

(2)建立複製集中每一個節點的日誌文件進程

      E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_0.logci

      E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_1.log路由

      E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_2.log

 (3)爲複製集中的每一個節點建立啓動時所需的配置文件

      第一個節點配置文件爲:E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_0.conf 內容以下:

      dbpath = E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_0

      logpath = E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_0.log

      journal = true

      port = 40000

      replSet = rs0

其中dbpath指向數據庫數據文件存放的路徑(在第一步中已建立好),logpath指向數據庫的日誌文件路徑(第二步中已建立好),journal表示對於此mongod實例是否啓動日誌功能,port爲實例監聽的端口號,rs0爲實例所在的複製集名稱,更多參數的意思能夠參考mongoDB手冊。

  第二個節點配置文件爲:E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_1.conf 內容以下:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_1

logpath = E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_1.log

journal = true

port = 40001

replSet = rs0

第三個節點配置文件爲:E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_2.conf 內容以下:

dbpath = E:\mongodb-win32-i386-2.4.3\db_rs0\data\rs0_2

logpath = E:\mongodb-win32-i386-2.4.3\db_rs0\logs\rs0_2.log

journal = true

port = 40002

replSet = rs0

(4)啓動上面三個節點對應的mongoDB實例

mongod –config  E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_0.conf

mongod –config  E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_1.conf

mongod –config  E:\mongodb-win32-i386-2.4.3\configs_rs0\rs0_2.conf

觀察一下每一個實例的啓動日誌,日誌中都有以下內容:

[rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)

[rsStart] replSet info you may need to run replSetInitiate -- rs.initiate() in the shell -- if that is not already done

上面日誌說明雖然已經成功啓動了三個實例,可是複製集還沒配置好,複製集的信息會保存在每一個mongod實例上的local數據庫中即local.system.replset上。按照上圖所描述那樣,你應該經過配置肯定哪一個節點爲primary、哪一個爲second、哪一個爲arbiter。下面開始配置複製集。

(5)啓動一個mongo客戶端,鏈接到上面的一個mongod實例

     >mongo --port 40000

運行如下命令初始化複製集

> rs.initiate()

{

    "info2" : "no configuration explicitly specified -- making one",

     "me" : "Guo:40000",

     "info" : "Config now saved locally.  Should come online in about a min e.",

     "ok" : 1

}

這個時候的複製集還只有剛纔這個初始化的成員,經過以下命令查看到。

> rs.conf()

{

        "_id" : "rs0",

        "version" : 1,

        "members" : [

                {

                        "_id" : 0,

                        "host" : "Guo:40000"

                }

        ]

}

按照mongoDB的默認設置,剛纔執行初始化命令的這個mongod實例將成爲複製集中的primary節點。

(6)接下來在複製集中添加上圖中的second節點和arbiter節點,繼續在上面那個mongod實例上執行以下命令:

rs0:PRIMARY> rs.add("Guo:40001")

{ "ok" : 1 }

rs0:PRIMARY> rs.addArb("Guo:40002")

{ "ok" : 1 }

注意此時命令的前綴變爲了:rs0:PRIMARY,說明當前執行命令的機器是複製集中primary機器,上面的命令經過rs.add()添加一個默認的second節點,rs.addArb()添加一個默認的arbiter節點。命令成功執行後,就會生成上圖所示那樣的一個複製集。

(7)觀察整個複製集的狀態信息,幾個重要參數會在後面說明。

rs0:PRIMARY> rs.status()

{

        "set" : "rs0",//複製集的名稱

        "date" : ISODate("2013-08-18T09:03:49Z"),

        "myState" : 1, //當前節點成員在複製集中的位置,如1表示primary,2表示secondry

        "members" : [//複製集的全部成員信息

                {

                        "_id" : 0, //成員編號

                        "name" : "Guo:40000",//成員所在的服務器名稱

                        "health" : 1,//成員在複製集中是否運行,1表示運行,0失敗

                        "state" : 1,//成員在複製集中的狀態,1是primary

                        "stateStr" : "PRIMARY",//成員在複製集中的狀態名稱

                        "uptime" : 2186,//成員的在線時間,單位是秒

                        "optime" : {//這個是用來進行同步用的,後面重點分析

                                "t" : 1376816431,

                                "i" : 1

                        },

                        "optimeDate" : ISODate("2013-08-18T09:00:31Z"),

                        "self" : true //成員爲當前命令所在的服務器

                },

                {

                        "_id" : 1,

                        "name" : "Guo:40001",

                        "health" : 1, ,//成員在複製集中是否運行,1表示運行

                        "state" : 2 ,//成員在複製集中的狀態,2是secondary

                        "stateStr" : "SECONDARY",

                        "uptime" : 306,

                        "optime" : {

                                "t" : 1376816431,

                                "i" : 1

                        },

                        "optimeDate" : ISODate("2013-08-18T09:00:31Z"),

                        "lastHeartbeat" : ISODate("2013-08-18T09:03:47Z"),

                        "lastHeartbeatRecv" : ISODate("2013-08-18T09:03:47Z"),

                        "pingMs" : 0,//此遠端成員到本實例間一個路由包的來回時間

                        "syncingTo" : "Guo:40000"//此成員須要從哪一個實例同步數據

                },

                {

                        "_id" : 2,

                        "name" : "Guo:40002",

                        "health" : 1,

                        "state" : 7, //成員在複製集中的狀態位置,7是arbiter

                        "stateStr" : "ARBITER",

                        "uptime" : 198,

                        "lastHeartbeat" : ISODate("2013-08-18T09:03:49Z"),

                        "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),

                        "pingMs" : 0,//此遠端成員到本實例間一個路由包的來回時間

                }

        ],

        "ok" : 1

}

    上面複製集狀態信息的輸出是基於primary實例的,也能夠再secondary實例上輸出複製集的狀態信息,包含的字段與上面大體相同。上面的輸出有些地方還需進一步解釋,如在arbiter成員節點上,沒有字段syncingTo,說明他不須要從primary節點上同步數據,由於它只是一個當主節點發生故障時,在複製集中剩下的secondary節點中選擇一個新的priamry節點的仲裁者,所以運行此實例的機器不須要太多的存儲空間。

上面輸出的字段中還有幾個時間相關的字段如:"date"表示當前實例所在服務器的時間,"lastHeartbeat"表示當前實例到此遠端成員最近一次成功發送與接收心跳包的時間,經過比較這個兩個時間能夠判斷當前實例與此成員相差的時間間隔,好比某個成員宕機了,本實例發像此宕機成員的心跳包就不會被成功接收,隨着時間推移,本實例的data字段值與此成員上的lastHeartbeat差值就會逐漸增長。

上面還有一個optime字段,這個字段的值說明了本實例最近一次更改數據庫的時間"t" : 1376816431以及每秒執行的操做數據庫的次數"i" : 1,此字段的值其實是從本實例上的local數據庫中的oplog.rs集合上讀取的,這個集合還詳細記錄了具體是什麼操做,如插入語句、修改語句等。複製集中的每個實例都會有一個這樣的數據庫和集合,若是複製集運行正常,理論上來講,每個mongod實例上此集合中的記錄應該相同。實際上mongoDB也是根據此集合來實現複製集中primary節點與secondary節點間的數據同步。

相關文章
相關標籤/搜索