【MongoDB】高可用方案之副本集(Replica Set)
Replicat Set比起傳統的Master - Slave結構而言,應用場景更加多,也有了自動failover的能力。
在mongo3.2的文件中明確寫道:
本文將簡單介紹mongodb副本集搭建。
〇 副本集結構圖
我在此處大致理解為“MySQL中1主2從+mha_manager”的結構。
Replication透過Oplog實現語句復現。
〇 副本整合員的屬性:
分別為Primary、Secondary(Secondaries)
Primary負責處理所有的write請求,並記錄到oplog(operation log)中。
Secondary負責複製oplog並應用這些write請求到他們自己的資料集中。(有一些類似於MySQL Replication)
所有的副本集都可以處理讀操作,但是需要設定。
最小化的副本集配置建議有三個成員:
1個Primary + 2個Secondary
或者
1個Primary + 1個Secondary + 1個Arbiter(仲裁者)
〇 Arbiter和選舉機制:
Arbiter可以作為副本集的一部分,但它不是一個資料副本,故它不會成為Primary。
Arbiter在Primary不可用的時候,作為一個選舉的角色存在。
如果Arbiter不存在,Primary掛掉的情況下,剩下的兩個Secondary則也會進行選舉。
在1個Primary + 2個Secondary的情況下,failover如下:
〇 搭建
實驗結構:
185(Arbiter)(後文用到)
186\187\188(1個Primary、2個Secondary)
在三臺機器上分別建立對應目錄然後啟動mongodb:
登入任意一臺副本集的mongo shell
此處用的是192.168.1.187
輸入:
初始化配置:
此時可以發現該mongodb例項已經成為PRIMARY了。
可以看一下這個副本集的各個成員的狀態:
〇 副本集複製狀態測試
在PRIMARY上insert:
在186、188任意SECONDARY上查詢:
同master - slave結構一樣,預設SECONDARY是不可讀的,需要執行rs.slaveOk()。
〇 failover測試
此時情況:
187:PRIAMRY
186、188:SECONDARY
停掉PRIAMRY:
(原SECONDARY)188上查到,此時188已經為PRIMARY了。
〇 在副本集中新增一個屬性為Arbiter的成員
當然此處只做新增實踐,實際上並不建議在Secondary-Primary-Secondary的結構上再多一個Arbiter成員形成偶數個節點。
文件寫到:
在192.168.1.185(另一臺)上啟動一個mongod例項:
在failover後的PRIMARY節點新增Arbiter
此時回到arbiter的mongo shell,發現正如文件所說,arbiter是不會存有副本集中資料的。
〇 參考文件:
Replication > Replica Set Tutorials > Replica Set Deployment Tutorials
Reference > mongo Shell Methods > Replication Methods
在mongo3.2的文件中明確寫道:
- Replica sets replace master-slave replication for most use cases.
- If possible, use replica sets rather than master-slave replication for all new production deployments.
本文將簡單介紹mongodb副本集搭建。
〇 副本集結構圖
我在此處大致理解為“MySQL中1主2從+mha_manager”的結構。
Replication透過Oplog實現語句復現。
〇 副本整合員的屬性:
分別為Primary、Secondary(Secondaries)
Primary負責處理所有的write請求,並記錄到oplog(operation log)中。
Secondary負責複製oplog並應用這些write請求到他們自己的資料集中。(有一些類似於MySQL Replication)
所有的副本集都可以處理讀操作,但是需要設定。
最小化的副本集配置建議有三個成員:
1個Primary + 2個Secondary
或者
1個Primary + 1個Secondary + 1個Arbiter(仲裁者)
〇 Arbiter和選舉機制:
Arbiter可以作為副本集的一部分,但它不是一個資料副本,故它不會成為Primary。
Arbiter在Primary不可用的時候,作為一個選舉的角色存在。
如果Arbiter不存在,Primary掛掉的情況下,剩下的兩個Secondary則也會進行選舉。
在1個Primary + 2個Secondary的情況下,failover如下:
〇 搭建
實驗結構:
185(Arbiter)(後文用到)
186\187\188(1個Primary、2個Secondary)
在三臺機器上分別建立對應目錄然後啟動mongodb:
-
mkdir -p /data/mongo_replset
- mongod --dbpath=/data/mongo_replset --logpath=/data/mongo_replset/mongo.log --fork --replSet=first_replset
登入任意一臺副本集的mongo shell
此處用的是192.168.1.187
- > use admin
輸入:
-
> cnf = {_id:"first_replset", members:[
-
{_id:1, host:"192.168.1.186:27017"},
-
{_id:2, host:"192.168.1.187:27017"},
-
{_id:3, host:"192.168.1.188:27017"},
-
]
-
}
-
-
輸出結果:
-
> {
-
"_id" : "first_replset",
-
"members" : [
-
{
-
"_id" : 1,
-
"host" : "192.168.1.186:27017"
-
},
-
{
-
"_id" : 2,
-
"host" : "192.168.1.187:27017"
-
},
-
{
-
"_id" : 3,
-
"host" : "192.168.1.188:27017"
-
}
-
]
- }
初始化配置:
-
> rs.initiate(cnf);
-
{ "ok" : 1 }
-
first_replset:OTHER>
-
first_replset:PRIMARY>
- first_replset:PRIMARY>
此時可以發現該mongodb例項已經成為PRIMARY了。
可以看一下這個副本集的各個成員的狀態:
-
first_replset:PRIMARY> rs.status();
-
{
-
"set" : "first_replset",
-
"date" : ISODate("2016-11-15T08:22:10.316Z"),
-
"myState" : 2,
-
"term" : NumberLong(0),
-
"heartbeatIntervalMillis" : NumberLong(2000),
-
"members" : [
-
{
-
"_id" : 1,
-
"name" : "192.168.1.186:27017",
-
"health" : 1,
-
"state" : 2,
-
"stateStr" : "SECONDARY",
- ……………………
-
},
-
{
-
"_id" : 2,
-
"name" : "192.168.1.187:27017",
-
"health" : 1,
-
"state" : 2,
-
"stateStr" : "PRIMARY",
- ……………………
-
},
-
{
-
"_id" : 3,
-
"name" : "192.168.1.188:27017",
-
"health" : 1,
-
"state" : 2,
-
"stateStr" : "SECONDARY",
- ……………………
-
}
-
],
-
"ok" : 1
- }
〇 副本集複製狀態測試
在PRIMARY上insert:
-
[root@192.168.1.187]# mongo 127.0.0.1/test
-
MongoDB shell version: 3.2.10
-
connecting to: 127.0.0.1/test
-
first_replset:PRIMARY> db.test_table.insert({"id": 1})
-
WriteResult({ "nInserted" : 1 })
-
first_replset:PRIMARY> db.test_table.find()
- { "_id" : ObjectId("582abba066fdf9fae28a1ba7"), "id" : 1 }
在186、188任意SECONDARY上查詢:
同master - slave結構一樣,預設SECONDARY是不可讀的,需要執行rs.slaveOk()。
-
first_replset:SECONDARY> rs.slaveOk()
-
first_replset:SECONDARY> db.test_table.find()
- { "_id" : ObjectId("582abba066fdf9fae28a1ba7"), "id" : 1 }
〇 failover測試
此時情況:
187:PRIAMRY
186、188:SECONDARY
停掉PRIAMRY:
-
first_replset:PRIMARY> use admin
-
switched to db admin
-
first_replset:PRIMARY> db.shutdownServer()
-
server should be down...
-
2016-11-15T16:31:25.921+0800 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
-
2016-11-15T16:31:27.299+0800 I NETWORK [thread1] Socket recv() errno:104 Connection reset by peer 127.0.0.1:27017
-
2016-11-15T16:31:27.299+0800 I NETWORK [thread1] SocketException: remote: (NONE):0 error: 9001 socket exception [RECV_ERROR] server [127.0.0.1:27017]
-
2016-11-15T16:31:27.299+0800 I NETWORK [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed
-
2016-11-15T16:31:27.302+0800 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
-
2016-11-15T16:31:27.302+0800 W NETWORK [thread1] Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused
-
2016-11-15T16:31:27.302+0800 I NETWORK [thread1] reconnect 127.0.0.1:27017 (127.0.0.1) failed failed
- >
(原SECONDARY)188上查到,此時188已經為PRIMARY了。
-
first_replset:PRIMARY> rs.status()
-
{
-
"set" : "first_replset",
-
"date" : ISODate("2016-11-15T16:31:45.773Z"),
-
"myState" : 1,
-
"term" : NumberLong(2),
-
"heartbeatIntervalMillis" : NumberLong(2000),
-
"members" : [
-
{
-
"_id" : 1,
-
"name" : "192.168.1.186:27017",
-
"health" : 1,
-
"state" : 2,
-
"stateStr" : "SECONDARY",
-
……………………
-
},
-
{
-
"_id" : 2,
-
"name" : "192.168.1.187:27017",
-
"health" : 0,
-
"state" : 8,
-
"stateStr" : "(not reachable/healthy)",
-
……………………
-
},
-
{
-
"_id" : 3,
-
"name" : "192.168.1.188:27017",
-
"health" : 1,
-
"state" : 1,
-
"stateStr" : "PRIMARY",
-
……………………
-
}
-
],
-
"ok" : 1
- }
〇 在副本集中新增一個屬性為Arbiter的成員
當然此處只做新增實踐,實際上並不建議在Secondary-Primary-Secondary的結構上再多一個Arbiter成員形成偶數個節點。
文件寫到:
- Only add an arbiter to sets with even numbers of voting members.
- If you add an arbiter to a set with an odd number of voting members, the set may suffer from tied elections.
在192.168.1.185(另一臺)上啟動一個mongod例項:
-
mkdir -p /data/arb
- mongod --dbpath=/data/arb/ --logpath=/data/arb/mongo.log --fork --replSet=first_replset
在failover後的PRIMARY節點新增Arbiter
-
first_replset:PRIMARY> rs.addArb("192.168.1.185:27017")
-
{ "ok" : 1 }
-
first_replset:PRIMARY> rs.status()
-
……………………
-
{
-
"_id" : 4,
-
"name" : "192.168.1.185:27017",
-
"health" : 1,
-
"state" : 7,
-
"stateStr" : "ARBITER",
-
……………………
-
}
- ……………………
此時回到arbiter的mongo shell,發現正如文件所說,arbiter是不會存有副本集中資料的。
-
first_replset:ARBITER> rs.slaveOk()
-
first_replset:ARBITER> use test;
-
switched to db test
-
first_replset:ARBITER> show tables;
-
first_replset:ARBITER> db.test_table.find();
- Error: error: { "ok" : 0, "errmsg" : "node is recovering", "code" : 13436 }
〇 參考文件:
Replication > Replica Set Tutorials > Replica Set Deployment Tutorials
Reference > mongo Shell Methods > Replication Methods
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29773961/viewspace-2128530/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MongoDB Replica Set 副本集實踐MongoDB
- MongoDB副本集replica set (二)--副本集環境搭建MongoDB
- mongodb 3.0 replica set 配置MongoDB
- 【Mongodb】如何建立mongodb的replica setMongoDB
- 搭建高可用MongoDB叢集(二): 副本集MongoDB
- mongodb 4.0副本集搭建MongoDB
- MongoDB 6.0.3副本集搭建MongoDB
- [MONGODB]: WHEN ARBITER REQUIRED FOR REPLICA SETMongoDBUI
- MongoDB搭建Replica Set複製集MongoDB
- mongodb replica set 和 nodejs中使用mongoose連線replicaMongoDBNodeJS
- docker 下部署mongodb Replica Set 叢集DockerMongoDB
- 【Mongodb】 Replica set 的讀寫分離MongoDB
- 小丸子學MongoDB系列之——部署Replica Set+Sharded ClusterMongoDB
- MongoDB日常運維-04副本集搭建MongoDB運維
- mongodb複製集(replica set)搭建及管理MongoDB
- 【Mongodb】Replica Set 的選舉策略之三MongoDB
- 【Mongodb】 Replica set 的 選舉策略之二MongoDB
- 【Mongodb】 Replica set 的選舉策略之一MongoDB
- 【Mongodb】 replica set 新增和刪除節點。MongoDB
- MongoDB之副本集MongoDB
- 搭建高可用MongoDB叢集(三):深入副本集內部機制MongoDB
- MongoDB日常運維-05副本集故障切換MongoDB運維
- MongoDB 4.2副本集新增/刪除副本(一主一副一仲裁)MongoDB
- Mongodb3.0.5副本集搭建及spring和java連線副本集配置MongoDBSpringJava
- MongoDB 4.2副本集自動故障轉移(一主一副一仲裁)MongoDB
- 利用Mongodb的複製集搭建高可用分片,Replica Sets + Sharding的搭建過程MongoDB
- MongoDB高階應用之高可用方案實戰(4)MongoDB
- 【Mongodb】 replica set 兩種新增節點方法的日誌分析MongoDB
- MongoDB系列-解決面試中可能遇到的MongoDB複製集(replica set)問題MongoDB面試
- 小丸子學MongoDB系列之——部署MongoDB副本集MongoDB
- 生成環境之Nginx高可用方案Nginx
- zanePerfor前端效能監控系統高可用之Mongodb副本集讀寫分離架構前端MongoDB架構
- MongoDB副本集MongoDB
- MongoDB高可用叢集搭建MongoDB
- 高可用的MongoDB叢集MongoDB
- 修改mongodb3.0副本集使用者密碼遇到的坑MongoDB密碼
- 搭建高可用MongoDB叢集(一):配置MongoDBMongoDB
- mongodb replica sets 測試MongoDB