搭建MongoDB复制集,一主两从一仲裁搭建在4个节点上,这四个节点分别为:
primary节点:39.100.20.128 —— server_D
secondary节点:39.100.20.149 —— server_B
secondary节点:39.100.201.91 —— server_A
arbiter节点:39.100.207.17 —— server_C
1. 安装MongoDB
在4个节点分别执行下面步骤安装MongoDB并启动。
[root@server_B ~]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.4.18.tgz
--2020-05-10 10:42:40-- https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.4.18.tgz
Resolving fastdl.mongodb.org (fastdl.mongodb.org)... 13.225.174.96, 13.225.174.13, 13.225.174.116, ...
Connecting to fastdl.mongodb.org (fastdl.mongodb.org)|13.225.174.96|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 102458415 (98M) [application/x-gzip]
Saving to: ‘mongodb-linux-x86_64-rhel62-3.4.18.tgz’
100%[===========================================================================================================================================>] 102,458,415 3.85MB/s in 33s
2020-05-10 10:43:15 (2.98 MB/s) - ‘mongodb-linux-x86_64-rhel62-3.4.18.tgz’ saved [102458415/102458415]
[root@server_B ~]# tar zxf mongodb-linux-x86_64-rhel62-3.4.18.tgz
[root@server_B ~]# mv mongodb-linux-x86_64-rhel62-3.4.18 /usr/local/mongodb
[root@server_B ~]# echo 'export PATH=$PATH:/usr/local/mongodb/bin'>> /etc/profile
[root@server_B ~]# source /etc/profile
[root@server_B ~]# groupadd mongo
[root@server_B ~]# useradd -g mongo mongo
[root@server_B ~]# mkdir -p /data/mongodb/data
[root@server_B ~]# mkdir -p /data/mongodb/log
[root@server_B ~]# chown -R mongo.mongo /data/mongodb/
[root@server_B ~]# vi /usr/local/mongodb/mongo.conf
[root@server_B ~]# cat /usr/local/mongodb/mongo.conf
#SERVER
fork = true
port = 27017
quiet = true
dbpath = /data/mongodb/data
logpath = /data/mongodb/log/mongod.log
logappend = true
journal = true
nohttpinterface = true
directoryperdb = true
#SLOW_LOG
profile = 1
slowms = 500
replSet = dbtest
oplogSize = 4096
storageEngine=wiredTiger
wiredTigerCacheSizeGB=1
wiredTigerCollectionBlockCompressor=snappy
[root@server_B ~]# cd /usr/local/mongodb/bin/
[root@server_B bin]# mongod -f /usr/local/mongodb/mongo.conf
about to fork child process, waiting until server is ready for connections.
forked process: 12388
child process started successfully, parent exiting
此时,4个节点MongoDB都已安装并启动。
2. 选择primary节点初始化
在4个节点中选择一个节点为primary节点,本文选择server_D节点为primary节点,在该节点中执行下述操作。
[root@server_D bin]# mongod -f /usr/local/mongodb/mongo.conf
about to fork child process, waiting until server is ready for connections.
forked process: 2804
child process started successfully, parent exiting
[root@server_D bin]# mongo --port 27017
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017/
MongoDB server version: 3.4.18
> rs.initiate({_id:'dbtest',members:[{_id:1,host:'39.100.20.128:27017'}]})
{ "ok" : 1 }
dbtest:SECONDARY> rs.status()
{
"set" : "dbtest",
"date" : ISODate("2020-05-10T03:03:05.658Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1589079777, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1589079777, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1589079777, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 1,
"name" : "39.100.20.128:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 285,
"optime" : {
"ts" : Timestamp(1589079777, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-10T03:02:57Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1589079745, 2),
"electionDate" : ISODate("2020-05-10T03:02:25Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
}
],
"ok" : 1
}
添加secondary节点
下面为添加其中一个,同样操作执行两次add。
dbtest:PRIMARY> rs.add('39.100.20.149:27017')
{ "ok" : 1 }
添加arb节点
dbtest:PRIMARY> rs.addArb('39.100.207.17:27017')
{ "ok" : 1 }
dbtest:PRIMARY> rs.status()
{
"set" : "dbtest",
"date" : ISODate("2020-05-10T03:05:41.991Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1589079939, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1589079939, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1589079939, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 1,
"name" : "39.100.20.128:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 441,
"optime" : {
"ts" : Timestamp(1589079939, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-10T03:05:39Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1589079745, 2),
"electionDate" : ISODate("2020-05-10T03:02:25Z"),
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "39.100.20.149:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 79,
"optime" : {
"ts" : Timestamp(1589079939, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1589079939, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-10T03:05:39Z"),
"optimeDurableDate" : ISODate("2020-05-10T03:05:39Z"),
"lastHeartbeat" : ISODate("2020-05-10T03:05:41.580Z"),
"lastHeartbeatRecv" : ISODate("2020-05-10T03:05:39.587Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 3
},
{
"_id" : 3,
"name" : "39.100.207.17:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 2,
"lastHeartbeat" : ISODate("2020-05-10T03:05:41.581Z"),
"lastHeartbeatRecv" : ISODate("2020-05-10T03:05:39.595Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 3
}
],
"ok" : 1
}
dbtest:PRIMARY>
自此搭建完毕。
可通过mongo --port 27017登录各节点MongoDB,即可看到各节点角色。
可在primary节点插入数据,再去secondary节点检查是否同步。
1.主机IP地址全部改变,集群启动失败。
[root@server_D bin]# mongo --port 27017
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017/
MongoDB server version: 3.4.18
dbtest:OTHER> rs.status()
{
"state" : 10,
"stateStr" : "REMOVED",
"uptime" : 248,
"optime" : {
"ts" : Timestamp(1589094778, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-10T07:12:58Z"),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"ok" : 0,
"errmsg" : "Our replica set config is invalid or we are not a member of it",
"code" : 93,
"codeName" : "InvalidReplicaSetConfig"
}
解决办法
在primary节点执行下述三步:
dbtest:OTHER> use admin
switched to db admin
dbtest:OTHER> cfg = {
...
... _id : "dbtest",
...
... members: [ { _id : 0, host : "39.99.189.77:27017" }, { _id : 1, host : "39.99.215.115:27017" }, { _id : 2, host : "39.99.210.143:27017" } , { _id : 3, host : "39.99.217.177:2
7017" }]
...
... }
{
"_id" : "dbtest",
"members" : [
{
"_id" : 0,
"host" : "39.99.189.77:27017"
},
{
"_id" : 1,
"host" : "39.99.215.115:27017"
},
{
"_id" : 2,
"host" : "39.99.210.143:27017"
},
{
"_id" : 3,
"host" : "39.99.217.177:27017"
}
]
}
dbtest:OTHER> rs.reconfig(cfg, {force : true})
{ "ok" : 1 }
----------------------------------------------------------
dbtest:OTHER> rs.status()
{
"set" : "dbtest",
"date" : ISODate("2020-05-10T15:45:46.091Z"),
"myState" : 2,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"appliedOpTime" : {
"ts" : Timestamp(1589094778, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1589094778, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "39.99.189.77:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 960,
"optime" : {
"ts" : Timestamp(1589094778, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-10T07:12:58Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 90200,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "39.99.215.115:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 14,
"optime" : {
"ts" : Timestamp(1589094768, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1589094768, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-05-10T07:12:48Z"),
"optimeDurableDate" : ISODate("2020-05-10T07:12:48Z"),
"lastHeartbeat" : ISODate("2020-05-10T15:45:41.360Z"),
"lastHeartbeatRecv" : ISODate("2020-05-10T15:45:41.363Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 90200
},
{
"_id" : 2,
"name" : "39.99.210.143:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2020-05-10T15:45:41.361Z"),
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 3,
"name" : "39.99.217.177:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2020-05-10T15:45:41.361Z"),
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "No route to host",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
}
],
"ok" : 1
}
dbtest:SECONDARY> rs.isMaster()
{
"hosts" : [
"39.99.189.77:27017",
"39.99.215.115:27017",
"39.99.210.143:27017",
"39.99.217.177:27017"
],
"setName" : "dbtest",
"setVersion" : 90200,
"ismaster" : true,
"secondary" : false,
"primary" : "39.99.189.77:27017",
"me" : "39.99.189.77:27017",
"electionId" : ObjectId("7fffffff0000000000000002"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"lastWriteDate" : ISODate("2020-05-10T15:48:20Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2020-05-10T15:48:20.849Z"),
"maxWireVersion" : 5,
"minWireVersion" : 0,
"readOnly" : false,
"ok" : 1
}
dbtest:PRIMARY> rs.status()
{
"set" : "dbtest",
"date" : ISODate("2020-05-10T15:48:26.801Z"),
"myState" : 1,
"term" : NumberLong(2),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"appliedOpTime" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
}
},
"members" : [
{
"_id" : 0,
"name" : "39.99.189.77:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1120,
"optime" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2020-05-10T15:48:20Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1589125698, 1),
"electionDate" : ISODate("2020-05-10T15:48:18Z"),
"configVersion" : 90200,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "39.99.215.115:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 175,
"optime" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2020-05-10T15:48:20Z"),
"optimeDurableDate" : ISODate("2020-05-10T15:48:20Z"),
"lastHeartbeat" : ISODate("2020-05-10T15:48:26.589Z"),
"lastHeartbeatRecv" : ISODate("2020-05-10T15:48:26.784Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "39.99.189.77:27017",
"syncSourceHost" : "39.99.189.77:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 90200
},
{
"_id" : 2,
"name" : "39.99.210.143:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2020-05-10T15:48:26.590Z"),
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 3,
"name" : "39.99.217.177:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 10,
"optime" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1589125700, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2020-05-10T15:48:20Z"),
"optimeDurableDate" : ISODate("2020-05-10T15:48:20Z"),
"lastHeartbeat" : ISODate("2020-05-10T15:48:26.589Z"),
"lastHeartbeatRecv" : ISODate("2020-05-10T15:48:26.425Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "39.99.189.77:27017",
"syncSourceHost" : "39.99.189.77:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 90200
}
],
"ok" : 1
}
发现其中有一节点显示不健康,拒绝连接,“lastHeartbeatMessage” : “Connection refused”,解决办法为:
首先将该节点移除,并去该节点关闭防火墙,执行 iptables -F,重启MongoDB,再将该节点添加进集群。
dbtest:PRIMARY> rs.remove('39.99.210.143:27017')
{ "ok" : 1 }
dbtest:PRIMARY> rs.addArb('39.99.210.143:27017')
{ "ok" : 1 }
2.Java程序访问MongoDB复制集的URL
mongodb://121.89.183.91:27017,121.89.186.3:27017,121.89.184.34:27017/business?
w=1&readPreference=secondarypreferred
business 为数据库名;
secondarypreferred 表示读优先secondary节点。
3.可视化工具
我选择的是Robo 3T 1.3.1,我使用的是SSH连接。
其中三个节点显示如下。
4.导入数据
将json格式的数据导入MongoDB,使用下述命令批量插入business(提前创建)数据库的customer (自动创建)collection。
[root@server_D bin]# ./mongoimport --db business --collection customer --file /root/xx/jsons/customer.json --numInsertionWorkers 100
2020-04-27T11:53:11.531+0800 connected to: localhost
2020-04-27T11:53:14.530+0800 [########################] business.customer 48.5 MB/48.5 MB (100.0%)
2020-04-27T11:53:17.529+0800 [########################] business.customer 48.5 MB/48.5 MB (100.0%)
2020-04-27T11:53:17.676+0800 [########################] business.customer 48.5 MB/48.5 MB (100.0%)
2020-04-27T11:53:17.676+0800 imported 250000 documents
[root@server_D bin]#