MongoDB之副本集
一、簡介
MongoDB 是一個基于分布式文件存儲的數據庫。由 C++ 語言編寫。旨在為 WEB 應用提供可擴展的高性能數據存儲解決方案。
MongoDB 是一個介于關系數據庫和非關系數據庫之間的產品,是非關系數據庫當中功能最豐富,最像關系數據庫的。
1.1副本集(replication)
MongoDB 副本集是一組mongod的進程,它們保存著相同的數據集。副本集提供了冗余和高可用,這是所有生產環境部署的基礎。在不同的數據庫服務中,存在著相同的數據,它提供了一定級別的容災,避免了單點故障。在一些情況下副本可以提供讀的能力,客戶端發來的讀請求可以分配到不同的服務上。一個副本集包含幾個數據承載節點和隨意的一個仲裁節點。數據承載節點中,只能有一個成員是主節點(primary),其他的節點都是從節點(secondary)。一個副本集中只用主節點有確認寫的能力,主節點在oplog中記錄下所有數據的變化,從節點復制主節點的oplog,并執行這些操作。這樣,從節點的數據與主節點保持一致。如果主節點不可用,從節點中將會選舉出新的主節點。
1.2仲裁者(arbiter)
你可以向副本集中添加額外的mongod實例作為仲裁者(arbiter)。仲裁者不保存數據,它只在心跳響應中和選舉請求中作為一個法定人數。由于仲裁節點不保存數據,所以相比數據節點,它占用更少的資源。如果你的數據集有偶數個節點,添加一個仲裁者節點可以保持選舉中的多數票。
1.3自動故障轉移(Automatic Failover)
當主節點不能和其他成員節點通信,超過10秒時,一個合法的從節點將舉行選舉,選舉它自己為新的主節點,第一個進行選舉的從節點如果收到了大多數的選票,它將成為新的主節點。失效轉移的過程大概會在1分鐘內完成,例如,副本集中的成員發現主節點不可用將花費10-30秒時間,其余的從節點選舉出新的主節點花費10-30秒時間。
1.4 優先級為0的數據集成員
一個優先級為0的成員不能成為主節點,也不能觸發選舉。除了這個限制,它和其他的從節點功能一樣,保持數據復制,接受讀操作,在選舉中投票。配置優先級為0的從節點,經常用于多數據中心的部署。例如,一個數據中心擁有一個主節點和一個從節點,第二個數據中心擁有一個優先級為0的從節點,這樣,只有第一個數據中心的成員可以成為主節點。
1.5 隱藏的數據集成員
隱藏成員復制主節點的數據,但是它對于客戶端的節點是不可見的。隱藏成員必須是優先級為0的,它不能成為主節點。db.isMaster()方法不能顯示隱藏成員,但是隱藏成員可以在選舉中進行選舉。在下面5成員的副本集中,4個從節點復制主節點的數據,但是一個從節點是隱藏的。
二、部署副本集
2.1 部署副本集
3個成員的副本集提供了足夠的冗余以避免更多的網絡分裂和其他的系統失敗。這個集合有足夠的能力處理更多的分布讀操作。副本集應該總是有奇數個成員,這可以使得選舉過程更順利。在生產環境部署時,你應該保持每一個mongod實例在一個單獨的機器上,當使用虛擬機時,你應該保持每一個mongod實例在一個獨立的主機服務上。
從MongoDB官網下載package,上傳到3臺機器上。我們這臺機器的ip為192.168.2.233,192.168.2.234,192.168.2.235,上傳的目錄是/usr/local。
解壓:
tar -zxvf mongodb-linux-x86_64-rhel70-3.6.2.tgz
MongoDB的數據存儲在data目錄的db目錄下,但是這個目錄在安裝過程不會自動創建,所以你需要手動創建data目錄,并在data目錄中創建db目錄。
mkdir -p /data/db
我們再創建/data/conf目錄,存儲MongoDB的配置文件
mkdir /data/confvim mongod.conf
配置的內容如下:
replication:
replSetName: "rs0"
net:
bindIp: 192.168.2.233
replSetName設置副本集的名稱,這里我們設置為“rs0”,bindIp設置為本機的ip,3臺機器的mongod實例設置為自己的ip。
然后,我們在3臺機器上,分別啟動mongod實例
./bin/mongod --config /data/conf/mongod.conf
mongod啟動的默認端口是27017。
使用mongo shell連接3個mongod實例中的一個
./bin/mongo --host 192.168.2.233
然后執行如下命令,設置副本集:
rs.initiate( {
_id : "rs0",
members: [
{ _id: 0, host: "192.168.2.233:27017" },
{ _id: 1, host: "192.168.2.234:27017" },
{ _id: 2, host: "192.168.2.235:27017" }
]
})
這樣,3個成員的副本集就設置完成了。
查看副本集的配置,運行如下命令:
rs.conf()
返回的結果如下:
{
"_id" : "rs0",
"version" : 1,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "192.168.2.233:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "192.168.2.234:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "192.168.2.235:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("585ab9df685f726db2c6a840")
}
}
確定副本集的主節點,運行如下命令:
{
"set" : "rs0",
"date" : ISODate("2018-02-08T11:08:15.457Z"),
"myState" : 1,
"term" : NumberLong(2),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"appliedOpTime" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.2.233:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 67,
"optime" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-02-08T11:08:09Z"),
"electionTime" : Timestamp(1518088058, 1),
"electionDate" : ISODate("2018-02-08T11:07:38Z"),
"configVersion" : 3,
"self" : true
},
{
"_id" : 1,
"name" : "192.168.2.234:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 46,
"optime" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-02-08T11:08:09Z"),
"optimeDurableDate" : ISODate("2018-02-08T11:08:09Z"),
"lastHeartbeat" : ISODate("2018-02-08T11:08:14.473Z"),
"lastHeartbeatRecv" : ISODate("2018-02-08T11:08:14.829Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.2.233:27017",
"configVersion" : 3
},
{
"_id" : 2,
"name" : "192.168.2.235:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 24,
"optime" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1518088089, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-02-08T11:08:09Z"),
"optimeDurableDate" : ISODate("2018-02-08T11:08:09Z"),
"lastHeartbeat" : ISODate("2018-02-08T11:08:14.474Z"),
"lastHeartbeatRecv" : ISODate("2018-02-08T11:08:15.020Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.2.234:27017",
"configVersion" : 3
}
],
"ok" : 1,
"operationTime" : Timestamp(1518088089, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1518088089, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
我們從返回的結果中,可以看到每個節點的狀態。
2.2 添加仲裁者節點
警告:一個副本集的仲裁者節點不要超過一個。
首先,為仲裁者節點創建數據庫目錄
mkdir /data/arb
以副本集的方式啟動仲裁者節點,并制定數據庫目錄:
mongod --port 27017 --dbpath /data/arb --replSet rs0 --bind_ip 192.168.2.236
向副本集中加入仲裁者,只有連接主節點才能加入仲裁者節點,前面的例子中,我們的主節點是192.168.2.233,然后執行如下命令:
rs.addArb("192.168.2.236:27017")
至此,創建副本集就介紹完了,希望對大家有幫助。