文章目錄
- 建立MongoDB副本集
-
- 安裝
- 配置
- 生成key
- 啟動MongoDB
- 建立叢集
- 使用Springboot Mongotemplate連接配接副本集操作
建立MongoDB副本集
MongoDB副本集實作故障自動切換至少需要以下配置為:
1.一個主節點,兩個從節點
2.一個主節點,一個從節點一個仲裁節點。
如果隻有一主一從節點,故障時無法選舉出主節點進而實作切換。
安裝
在三台伺服器上安裝MongoDB,同時在主節點資料庫上提前建立好有副本集權限的使用者。
當然你也可以選擇安裝在同一台伺服器上(除了測試用,不然意義不大)。
安裝部分請自行搜尋網上資料,在此不再贅述。
配置
修改三個Mongo配置檔案,都加入以下配置
第一個參數是指定副本集
第二個參數是使用key進行安全認證
replSet=test_resplset
keyFile=/usr/local/mongodb/conf/mongodb_key
如果配置中有
auth=on
項,請删除,否則會造成節點沒有權限連接配接。副本集使用key檔案進行安全認證。
生成key
> openssl rand -base64 102 /usr/local/mongodb/conf/mongodb_key
生成key檔案
> chmod 600 /usr/local/mongodb/conf/mongodb_key
賦600權限
啟動MongoDB
正常啟動三個Mongo服務即可
> /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/mongodb.conf
然後連接配接一台你想使其成為主節點的資料庫。
建立叢集
連接配接主節點後,輸入:
> config = {
"_id" : "test_resplset",
"members" : [
{
"_id" : 0,
"host" : "192.168.1.123:27020",
"priority" : 99
},
{
"_id" : 1,
"host" : "192.168.1.124:27021"
},
{
"_id" : 2,
"host" : "192.168.1.125:27022",
"arbiterOnly" : true
}
] }
arbiterOnly: true
指這個節點為仲裁節點。
這裡無論你的三個服務是否在同一個伺服器上,都不要使用
127.0.0.1
位址,否則稍後連接配接資料庫的時候會連接配接不上(域名我沒測試過,各位可以自己嘗試)。
> rs.initiate(config)
初始化叢集。這兩步隻需要在主節點上操作一次即可。
出現
{"ok":1}
代表配置成功。
如果此處報沒有權限認證的錯誤,請先使用有副本集權限的使用者進行權限認證。
> use admin
> db.auth("user","pwd")
如果提示本節點不是主節點,請關閉主節點資料庫,注釋掉指定副本集參數後單機啟動,然後進行操作。操作完成後重新以副本集啟動。
> rs.status() // 檢視叢集狀态
{
"set" : "test_resplset",
"date" : ISODate("2019-04-19T08:39:05.420Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1555663135, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1555663135, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1555663135, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1555663135, 1),
"t" : NumberLong(1)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1555663085, 1),
"members" : [
{
"_id" : 0,
"name" : "192.168.1.123:27020",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 795,
"optime" : {
"ts" : Timestamp(1555663135, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-04-19T08:38:55Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1555663083, 1),
"electionDate" : ISODate("2019-04-19T08:38:03Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.1.124:27021",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 71,
"optime" : {
"ts" : Timestamp(1555663135, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1555663135, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-04-19T08:38:55Z"),
"optimeDurableDate" : ISODate("2019-04-19T08:38:55Z"),
"lastHeartbeat" : ISODate("2019-04-19T08:39:03.693Z"),
"lastHeartbeatRecv" : ISODate("2019-04-19T08:39:04.714Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.1.123:27020",
"syncSourceHost" : "192.168.1.123:27020",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.1.125:27022",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 71,
"lastHeartbeat" : ISODate("2019-04-19T08:39:03.691Z"),
"lastHeartbeatRecv" : ISODate("2019-04-19T08:39:03.615Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1555663135, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1555663135, 1),
"signature" : {
"hash" : BinData(0,"KMcQWa4w+xlc02Atf6a/uv6DH9I="),
"keyId" : NumberLong("6681522073669468161")
}
}
}
可以看到一個主節點,一個仲裁節點,一個從節點。
使用Springboot Mongotemplate連接配接副本集操作
人懶,此處就簡單使用單元測試做個例子吧。上代碼:
@Data
@Document(collection = "test")
class Author {
private String name;
}
@Test
public void testReadMongoReplSet() {
MongoClientURI mongoClientURI = new MongoClientURI("mongodb://user:[email protected]:27020,192.168.1.124:27021/test_resplset?replicaSet=test_resplset&authSource=test_resplset&readPreference=secondaryPreferred&safe=true&authMechanism=SCRAM-SHA-1&maxPoolSize=500&minPoolSize=10");
SimpleMongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory);
System.out.println(mongoTemplate.find(new Query(),Author.class));
try {
mongoDbFactory.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testWriteMongoReplSet() {
MongoClientURI mongoClientURI = new MongoClientURI("mongodb://user:[email protected]:27020,192.168.1.124:27021/test_resplset?replicaSet=test_resplset&authSource=test_resplset&readPreference=secondaryPreferred&safe=true&authMechanism=SCRAM-SHA-1&maxPoolSize=500&minPoolSize=10");
SimpleMongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory);
Author a= new Author();
a.setName("testWrite");
mongoTemplate.insert(a);
try {
mongoDbFactory.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
mongodb://user:[email protected]:27020,192.168.1.124:27021/test_resplset?replicaSet=test_resplset&authSource=test_resplset&readPreference=secondaryPreferred&safe=true&authMechanism=SCRAM-SHA-1&maxPoolSize=500&minPoolSize=10
我們來看下這連結位址。
首先整體格式應該滿足:
mongodb://[username:[email protected]]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
-
使用者名密碼沒啥好說的。username:password
-
這一段填的是主從節點的位址,仲裁節點不需要填寫。192.168.1.123:27020,192.168.1.124:27021
-
這裡是指的資料庫名/test_resplset
-
指定副本集(這裡是因為我資料庫名和副本集名建的一樣,實際并不一樣,自己注意)replicaSet=test_resplset
-
認證的資料庫authSource=test_resplset
-
讀走從節點readPreference=secondaryPreferred
-
safe=true
在執行更新操作之後,驅動都會發送getLastError指令來確定更新成功
…
執行成功時,會在控制台列印相應日志,能夠看到讀寫走的哪個服務。
192.168.1.123:27020
為主節點,寫服務走它。
192.168.1.124:27021
為從節點,讀服務走它。
192.168.1.125:27022
為仲裁節點,連接配接時不需要寫上。
如果是Springboot 直接使用
@Autowired
注入
MongoTemplate
,同時在配置檔案中加入那串位址就行,沒上面這麼麻煩。
本文内容為本人學習MongoDB副本集過程中的簡單知識總結,以防止自己遺忘。如有錯誤,歡迎批評指正。