MongoDB3.6之Replica Set初步體驗
Replica Set在國內叫做複本集,簡單來說就是一份資料在多個地方儲存。
1.為什麼要用複本集,什麼時候使用複本集?
有人說一份資料在多個地方儲存佔用了大量的額外空間,是一種浪費。
這個說法不能說對也不能說不對,要從不同的角度考慮。如果公司的業務量很少,資料不多,一台伺服器就可以搞定,那就不需要將一份資料存放區在多個地方。隨著公司的發展壯大,業務量越來越多,資料也越來越多,這時就需要考慮使用分布式叢集的方式來解決了,將資料分散在不同的伺服器中。此時仍可以不使用副本,通過將資料分散在不同的伺服器中來分散各伺服器的壓力也可以跟上公司目前的業務量。如果公司規模進一步擴大,使用者量越來越多,有可能很多客戶要訪問同一份資源,此時就有可能造成存放該資源的伺服器壓力過大。副本的必要性就顯現出來了。
2.使用複本集有什麼好處?
複本集提供了容錯性,高可用性。當然容災備份,讀寫分離等也使用到了副本。
3.MongoDB Replica Set叢集介紹
先上一個典型的 Replica Set圖:
為方便介紹,以下簡稱rs叢集
(1).rs叢集是由多個Mongod執行個體節點群組成,其中只有一個節點是primary,其它節點是secondary,還有一個是可有可無的仲裁節點。當叢集有偶數個節點時,通過會添加一個仲裁節點,如果叢集有奇數個節點時,就不需要使用仲裁節點了。仲裁節點不儲存資料,只用於投票選舉出哪個節點是primary,而且仲裁節點不要求有專門的伺服器,但不能運行在已經安裝了primary或secondary節點的伺服器上,可以運行在應用或監控伺服器上(之前看到有人說仲裁節點除了投票外,還可以在primary節點失效後,在secondary節點中再選舉出一個primary,這是不對的,仲裁節點的作用僅僅是有一票之權)。
(2).primary用於接收client的讀和寫請求,並記錄動作記錄,secondary用於從primary處非同步同步primary的動作記錄,並更新自己的資料集。通常情況下secondary不能響應client的讀操作,以免讀取髒資料。但rs叢集有多個資料中心時,client可以請求讀取secondary資料,當primay在北京的伺服器上,其中一個Secondary在重慶,重慶的使用者在讀取資料時,考慮到地理位置和網速的關係,可選擇唯讀primary,primary優先,唯讀secondary,secondary優先和讀取最近(nearest)節點的資料。
(3).當primary不能訪問時,剩下的secondary節點中會再選出一個primary節點。
4.RS叢集部署樣本
(1).有三台伺服器,由於是奇數伺服器,所以不選擇仲裁節點。
(2).下載MongodDB手動安裝版(我下載的是Linux 64位版本),並解壓到一個目錄下,將解壓的檔案夾名字改成mongoDB,進入mongoDB目錄,建立一個設定檔mongod.conf
#mongod.conf
#資料儲存路徑
dbpath=mongodb/data/mongod
#日誌儲存路徑
logpath=mongodb/log/mongod.log
logappend=true
#後台運行儲存的進程pid
pidfilepath=/home/yanggy/mongodb/mongod.pid
#每個資料庫一個目錄
directoryperdb=true
#replica set的名字
replSet=testrs
#綁定IP與Host
bind_ip=server1
port=27001
#記錄檔大小
oplogSize=100
#後台運行
fork=true
#不提前載入資料到記憶體
noprealloc=true
將此設定檔複製到其它伺服器中,修改綁定的IP即可,並手動在各伺服器建立相應的資料和日誌目錄。
(3).在各伺服器啟動mongod執行個體
mongod -f mongodb/mongod.conf
(4).使用mongo串連其中一台伺服器
mongo --host server1 --port 27001
(5).初始化rs叢集
> cfg = {_id:"testrs",members:[{_id:0,host:"server1:27001",priority:3},
{_id:1,host:"server2:27001",priority:2},
{_id:2,host:"server3:27001",priority:1}]}
輸出:
{
"_id" : "testrs",
"members" : [
{
"_id" : 0,
"host" : "server1:27001",
"priority" : 3
},
{
"_id" : 1,
"host" : "server2:27001",
"priority" : 2
},
{
"_id" : 2,
"host" : "server3:27001",
"priority" : 1
}
]
}
>rs.initiate(cfg)
輸出:
{
"ok" : 1,
"operationTime" : Timestamp(1521190572, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1521190572, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
>rs.status()
輸出:
{
"set" : "testrs",
"date" : ISODate("2018-03-16T08:56:23.948Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"appliedOpTime" : {
"ts" : Timestamp(1521190572, 1),
"t" : NumberLong(-1)
},
"durableOpTime" : {
"ts" : Timestamp(1521190572, 1),
"t" : NumberLong(-1)
}
},
"members" : [
{
"_id" : 0,
"name" : "server1:27001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 220,
"optime" : {
"ts" : Timestamp(1521190572, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-03-16T08:56:12Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1521190582, 1),
"electionDate" : ISODate("2018-03-16T08:56:22Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "server2:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11,
"optime" : {
"ts" : Timestamp(1521190572, 1),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(1521190572, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-03-16T08:56:12Z"),
"optimeDurableDate" : ISODate("2018-03-16T08:56:12Z"),
"lastHeartbeat" : ISODate("2018-03-16T08:56:22.733Z"),
"lastHeartbeatRecv" : ISODate("2018-03-16T08:56:19.659Z"),
"pingMs" : NumberLong(0),
"configVersion" : 1
},
{
"_id" : 2,
"name" : "server3:27001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11,
"optime" : {
"ts" : Timestamp(1521190572, 1),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(1521190572, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-03-16T08:56:12Z"),
"optimeDurableDate" : ISODate("2018-03-16T08:56:12Z"),
"lastHeartbeat" : ISODate("2018-03-16T08:56:22.733Z"),
"lastHeartbeatRecv" : ISODate("2018-03-16T08:56:19.641Z"),
"pingMs" : NumberLong(0),
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1521190572, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1521190582, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
可以看到priority值越大的節點越有可能成為primary。
好了,相信大家對Replica Set已經有了初步體驗和認識,如果上文中有什麼表述的不準備或者錯誤的地方,歡迎指出,大家共同探討進步。
本文永久更新連結地址:https://www.bkjia.com/Linux/2018-03/151492.htm