MongoDB 是高性能 NoSQL 資料庫, 本身也支援高可靠性, Replication Set 設定簡單, 至少以三個節點組成, 通常為一個 Primary 負責讀寫, 兩個 Secondary 作為備援。本次試驗採用 Percona Server for MongoDB 4.2.6, 使用三個 Debian Linux 10 為作業系統的虛擬機。

虛擬機的 IP 位址與 hostname 設定:
192.168.1.211 mongodb1
192.168.1.212 mongodb2
192.168.1.213 mongodb3
mongodb1 將作為 Primary, mongodb2 與 mongodb3 為 Secondary

安裝 Percona Server for MongoDB, 採用 4.2 版
wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
percona-release enable psmdb-42 release
apt-get update
apt-get install percona-server-mongodb


編輯 MongoDB設定檔 /etc/mongod.conf
nano /etc/mongod.conf

預設值 network interfaces 是 0.0.0.0, 請改為內網 IP 位置
# network interfaces
net:
port: 27017
bindIp: 192.168.1.211

其他兩台 Secondary 照做

修改 Replication Set
replication:
replSetName: rs0

給予 Replication Set 名稱 "rs0"

重新啟動 MongoDB
service mongod restart


使用 Mongo Shell 進入 Primary Server
mongo 192.168.1.211

先來建個簡單的資料庫
use testdb
db.users.save({name:'Ryan Lai'})
db.users.save({name:'John Smith'})
db.users.save({name:'Michael Jordan'})

這樣就建立了"testdb"資料庫與名為"users"的collection (相當於SQL資料庫的table), 裡面有三筆資料

試著列出全部資料
db.users.find()

顯示結果
{ "_id" : ObjectId("5ec79bae6ae8db196a930ba0"), "name" : "Ryan Lai" }
{ "_id" : ObjectId("5ec79bd66ae8db196a930ba1"), "name" : "John Smith" }
{ "_id" : ObjectId("5ecb5e41708692f26fd9e7a0"), "name" : "Michael Jordan" }


接著就來設定 Replication Set
rs.initiate()

目前只會加入自己"mongodb1"這台機器, 陸續加入其他機器
rs.add( { host: "192.168.1.212:27017", priority: 1, votes: 1 } )
rs.add( { host: "192.168.1.213:27017", priority: 1, votes: 1 } )


顯示 Replication Set 的狀態
{
"_id" : "rs0",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "192.168.1.211:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {

},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "192.168.1.212:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {

},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "192.168.1.213: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,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {

},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5ecb62716d16965bba227d2c")
}
}


到其他機器看看資料由沒有複寫過去, 例如到 mongodb3 這台 Secondary Server
mongo 192.168.1.213


試著列出users裡的資料
use testdb
db.users.find()


結果跑出錯誤訊息
Error: error: {
"operationTime" : Timestamp(1590395341, 1),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk",
"$clusterTime" : {
"clusterTime" : Timestamp(1590395341, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}

在 Replication Set 裡 Secondary 是無法直接操作, 需要下此指令
rs.slaveOk()

再查詢一次就出現了
db.users.find()

其結果
{ "_id" : ObjectId("5ec79bae6ae8db196a930ba0"), "name" : "Ryan Lai" }
{ "_id" : ObjectId("5ec79bd66ae8db196a930ba1"), "name" : "John Smith" }
{ "_id" : ObjectId("5ecb5e41708692f26fd9e7a0"), "name" : "Michael Jordan" }


刪掉剛才的測試資料, 在 mongodb1 上執行
db.users.drop()

這會刪除"users"內所有資料
回到 mongodb3, 再跑一次 db.users.find() 也會沒有資料出來

退出 Mongo Shell
exit


以上是 MongoDB replication Set 的簡單試驗。
記錄一下
文章分享
評分
評分
複製連結

今日熱門文章 網友點擊推薦!