MongoDB 复制集
参考 MongoDB学习札记第八篇之Replica Set 实战
参考 MongoDB 3.0 复制集集群搭建及安全认证实践
参考 MongoDB 3.0 WT引擎参考配置文件
参考 MongoDB 副本集的原理. 搭建. 应用
准备三台mongo服务器 分别为 43.241.222.110 42.96.194.60 和 45.63.50.67 搭建复制集
如果对于怎么安装Mongodb还不清楚的同学可以查看我之前的学习札记
三台MongoDB服务器的配置文件均为 /etc/mongod.cnf
storage:
dbPath: "/data/home/data/RSMongoDB"
engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 20
collectionConfig:
blockCompressor: snappy
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
logAppend: true
processManagement:
fork: true
net:
#bindIp: 127.0.0.1,43.241.222.110,42.96.194.60 不能绑定外网访问ip,局域网的貌似可以,只能在iptable设定允许指定ip访问27017
#bindIp: 0.0.0.0
port: 27017
# Enable the HTTP interface (Defaults to port 28017).
http:
enabled: false
第一步:
在三台机器上分别运行(都要运行)
root@ubuntu:/usr/local/mongodb#mongod -f /etc/mongod.cnf --replSet CoamReSet
注意这里的 —replSet 参数指定了副本集的名称,每一个副本集都有一个唯一的名称.
等到三台机器都启动完了之后.使用mongo客户端登录其中一台mongod服务器.这里我登录到 43.241.222.110 这台机器
root@ubuntu:~# mongo
登录之后要切换到admin数据库,这样我们可以进行副本集的配置,具体怎么配置,代码如下:
> use admin
switched to db admin
定义副本集配置变量,这里的 _id:”repset” 和上面命令参数 “ –replSet repset” 要保持一样.
> config = {_id:"CoamReSet",members:[
{_id:0,host:"43.241.222.110:27017","priority":1},
{_id:1,host:"42.96.194.60:27017","priority":1},
{_id:2,host:"45.63.50.67:27017","priority":0}]}
输出
{
"_id" : "CoamReSet",
"members" : [
{
"_id" : 0,
"host" : "43.241.222.110:27017"
},
{
"_id" : 1,
"host" : "42.96.194.60:27017"
},
{
"_id" : 2,
"host" : "45.63.50.67:27017"
}
]
}
初始化副本集配置
> rs.initiate(config);
输出成功
{ "ok" : 1 }
注意:新创建副本集必须要数据库没有数据,否则初始化会提示以下错误:
{
"ok" : 0,
"errmsg" : "'42.96.194.60:27017' has data already, cannot initiate set.",
"code" : 110
}
先定义 config 的配置信息, 然后通过 rs.initiate(config) 方法,将配置信息初始化.这两个步骤完成之后就表示我们的副本集配置信息初始化完成了,在这个CoamReSet的副本集中我们定义了三台主机(注意在定义配置信息的时候指定的 _id 必须和我们启动mongod的时候指定的参数 —replSet 这个参数的值是一样的.)
过一会,mongodb就会帮我们选举出Primary节点和Secondary节点了.那在mongo客户端,我们可以通过 rs.status() 来查看副本集的状态信息
CoamReSet:SECONDARY> rs.status()
{
"set" : "CoamReSet",
"date" : ISODate("2015-10-01T09:45:34.924Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "43.241.222.110:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 167,
"optime" : Timestamp(1443692712, 1),
"optimeDate" : ISODate("2015-10-01T09:45:12Z"),
"electionTime" : Timestamp(1443692715, 1),
"electionDate" : ISODate("2015-10-01T09:45:15Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "42.96.194.60:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 21,
"optime" : Timestamp(1443692712, 1),
"optimeDate" : ISODate("2015-10-01T09:45:12Z"),
"lastHeartbeat" : ISODate("2015-10-01T09:45:33.166Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T09:45:33.564Z"),
"pingMs" : 16,
"configVersion" : 1
},
{
"_id" : 2,
"name" : "45.63.50.67:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 21,
"optime" : Timestamp(1443692712, 1),
"optimeDate" : ISODate("2015-10-01T09:45:12Z"),
"lastHeartbeat" : ISODate("2015-10-01T09:45:32.949Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T09:45:33.973Z"),
"pingMs" : 183,
"configVersion" : 1
}
],
"ok" : 1
}
其中name表示我么你的主机, health表示主机是否健康(0/1) , state(主节点(1)还是从节点(2),或者是不可达节点)
如果上面信息正常显示出来说明整个副本集群已经建立起来了.这时候我们来验证一下是否是真的能够自动备份数据,是否能够自动从失败中恢复,自动选举新的Primary节点.
这个实验我们这样来做:
先往 Primary 节点(43.241.222.110)插入数据,在 42.96.194.60 和 45.63.50.67 两台 Secondary 节点中查询数据,验证是否能够正常的同步机器.
先往 Primary 节点(43.241.222.110)插入数据
CoamReSet:PRIMARY> use test
switched to db test
CoamReSet:PRIMARY> show collections
CoamReSet:PRIMARY> db.guids.insert({"name":"replica set","author":"webinglin"})
WriteResult({ "nInserted" : 1 })
CoamReSet:PRIMARY> exit
bye
在 45.63.50.67 Secondary 节点中查询数据,验证是否能够正常的同步机器.
root@ubuntu:~# mongo --host 45.63.50.67
MongoDB shell version: 3.0.3
connecting to: 45.63.50.67:27017/test
Server has startup warnings:
2015-06-09T17:03:27.744-0700 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not re commended.
2015-06-09T17:03:27.744-0700 I CONTROL [initandlisten]
2015-06-09T17:03:27.745-0700 I CONTROL [initandlisten]
2015-06-09T17:03:27.745-0700 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-06-09T17:03:27.745-0700 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2015-06-09T17:03:27.745-0700 I CONTROL [initandlisten]
CoamReSet:SECONDARY> show dbs
2015-06-09T17:13:49.138-0700 E QUERY Error: listDatabases failed:{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }
at Error (<anonymous>)
at Mongo.getDBs (src/mongo/shell/mongo.js:47:15)
at shellHelper.show (src/mongo/shell/utils.js:630:33)
at shellHelper (src/mongo/shell/utils.js:524:36)
at (shellhelp2):1:1 at src/mongo/shell/mongo.js:47
CoamReSet:SECONDARY> use test
switched to db test
CoamReSet:SECONDARY> db.guids.find()
Error: error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
CoamReSet:SECONDARY> rs.slaveOk()
CoamReSet:SECONDARY> rs.slaveOk()
CoamReSet:SECONDARY> db.guids.find()
{ "_id" : ObjectId("557780ebd147e9391020860d"), "name" : "replica set", "author" : "webinglin" }
CoamReSet:SECONDARY> show collections()
2015-06-09T17:14:24.219-0700 E QUERY Error: don't know how to show [collections()]
at Error (<anonymous>)
at shellHelper.show (src/mongo/shell/utils.js:733:11)
at shellHelper (src/mongo/shell/utils.js:524:36)
at (shellhelp2):1:1 at src/mongo/shell/utils.js:733
CoamReSet:SECONDARY> show collections
guids
system.indexes
CoamReSet:SECONDARY> exit
bye
在 42.96.194.60 Secondary 节点中查询数据,验证是否能够正常的同步机器.
root@ubuntu:~# mongo --host 42.96.194.60
MongoDB shell version: 3.0.3
connecting to: 42.96.194.60:27017/test
Server has startup warnings:
2015-06-09T17:03:11.647-0700 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not re commended.
2015-06-09T17:03:11.647-0700 I CONTROL [initandlisten]
2015-06-09T17:03:11.647-0700 I CONTROL [initandlisten]
2015-06-09T17:03:11.648-0700 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-06-09T17:03:11.648-0700 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2015-06-09T17:03:11.648-0700 I CONTROL [initandlisten]
CoamReSet:SECONDARY> rs.slaveOk()
CoamReSet:SECONDARY> show dbs
local 1.078GB
test 0.078GB
CoamReSet:SECONDARY> use test
switched to db test
CoamReSet:SECONDARY> show collections
guids
system.indexes
CoamReSet:SECONDARY> db.guids.find()
{ "_id" : ObjectId("557780ebd147e9391020860d"), "name" : "replica set", "author" : "webinglin" }
CoamReSet:SECONDARY> exit
bye
至此,整个验证过程说明了我们集群部署是成功的.数据能够正常同步了.
那么接下来我们还要验证另一种情况,Primary异常终止之后(43.241.222.110),另外两个Secondary节点会不会自动选举出新的Primary节点呢?
这个实验我们这样处理: 将 43.241.222.110 机器的mongod服务停止掉,然后再来连接 42.96.194.60 或者 45.63.50.67 任意一台机器,通过 rs.status() 查看集群状态.
在Primary节点(43.241.222.110)通过 ps -e | grep mongod 查看mongod服务是否开启,然后通过 killall mongod 或者 kill -15 <进程号> 来杀死mongod进程
root@ubuntu:~# ps -e | grep mongod
3279 pts/0 00:00:19 mongod
root@ubuntu:~# killall mongod
登陆从节点 42.96.194.60 ,查看mongo服务器状态
root@ubuntu:~# mongo --host 42.96.194.60
MongoDB shell version: 3.0.3
connecting to: 42.96.194.60:27017/test
Server has startup warnings:
2015-06-09T17:03:11.647-0700 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2015-06-09T17:03:11.647-0700 I CONTROL [initandlisten]
2015-06-09T17:03:11.647-0700 I CONTROL [initandlisten]
2015-06-09T17:03:11.648-0700 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-06-09T17:03:11.648-0700 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2015-06-09T17:03:11.648-0700 I CONTROL [initandlisten]
CoamReSet:SECONDARY> rs.status()
{
"set" : "CoamReSet",
"date" : ISODate("2015-10-01T10:09:57.981Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "43.241.222.110:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : Timestamp(0, 0),
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2015-10-01T10:09:56.226Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T10:07:54.850Z"),
"pingMs" : 18,
"lastHeartbeatMessage" : "Failed attempt to connect to 43.241.222.110:27017; couldn't connect to server 43.241.222.110:27017 (43.241.222.110), connection attempt failed", "configVersion" : -1
},
{
"_id" : 1,
"name" : "42.96.194.60:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1577,
"optime" : Timestamp(1443693679, 1),
"optimeDate" : ISODate("2015-10-01T10:01:19Z"),
"electionTime" : Timestamp(1443694079, 1),
"electionDate" : ISODate("2015-10-01T10:07:59Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 2,
"name" : "45.63.50.67:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1481,
"optime" : Timestamp(1443693679, 1),
"optimeDate" : ISODate("2015-10-01T10:01:19Z"),
"lastHeartbeat" : ISODate("2015-10-01T10:09:56.891Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T10:09:57.259Z"),
"pingMs" : 440,
"configVersion" : 1
}
],
"ok" : 1
}
CoamReSet:SECONDARY> exit
bye
通过上面这段代码的观察,我们发现,当把原来的Primary节点停止掉后(43.241.222.110停止), 那么整个mongodb的副本集群会重新选举出新的Primary节点( 42.96.194.60 机器)
为了验证一下新选举的Primary是否正常,我们再次验证一把数据的同步情况,先连接到 42.96.194.60 主节点,将原来的数据删掉,再到 45.63.50.67 SECONDARY 进行验证,数据是否也被删除
连接到 42.96.194.60 主节点,将原来的数据删掉
root@ubuntu:~# mongo --host 42.96.194.60
CoamReSet:PRIMARY> use test
switched to db test
CoamReSet:PRIMARY> show collections
guids
CoamReSet:PRIMARY> db.guids.find()
{ "_id" : ObjectId("560d03099548a3e5bb8b03bf"), "name" : "replica set", "author" : "webinglin" }
{ "_id" : ObjectId("560d046f9548a3e5bb8b03c0"), "name" : "zhang", "author" : "yafei..." }
CoamReSet:PRIMARY> db.guids.remove({name:"zhang"})
WriteResult({ "nRemoved" : 1 })
CoamReSet:PRIMARY> db.guids.find()
{ "_id" : ObjectId("560d03099548a3e5bb8b03bf"), "name" : "replica set", "author" : "webinglin" }
CoamReSet:PRIMARY> exit
bye
再到 45.63.50.67 SECONDARY 进行验证,数据是否也被删除
root@ubuntu:~# mongo --host 45.63.50.67
CoamReSet:SECONDARY> rs.slaveOk()
CoamReSet:SECONDARY> db.guids.find()
{ "_id" : ObjectId("557780ebd147e9391020860d"), "name" : "replica set", "author" : "webinglin" }
CoamReSet:SECONDARY> exit
bye
实践后发现,先选举的Primary节点也正常工作.我们的整个Mongodb副本集群测试完成.
动态添加节点,删除节点.
在开始这个实验之前,先把 43.241.222.110 的机器重新启动,然后用mongo客户端连到 43.241.222.110 进行验证数据是否也同步了.
登录 43.241.222.110 之后,我们发现数据也同步了,然后43.241.222.110节点变成了 Secondary 节点了.
root@ubuntu:~# mongo
CoamReSet:SECONDARY> rs.slaveOk()
CoamReSet:SECONDARY> show dbs
local 0.000GB
syData 0.000GB
test 0.000GB
CoamReSet:SECONDARY> use test
switched to db test
CoamReSet:SECONDARY> show collections
guids
CoamReSet:SECONDARY> db.guids.find()
{ "_id" : ObjectId("560d03099548a3e5bb8b03bf"), "name" : "replica set", "author" : "webinglin" }
CoamReSet:SECONDARY> rs.status()
{
"set" : "CoamReSet",
"date" : ISODate("2015-10-01T10:21:53.366Z"),
"myState" : 2,
"syncingTo" : "42.96.194.60:27017",
"members" : [
{
"_id" : 0,
"name" : "43.241.222.110:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 68,
"optime" : Timestamp(1443694583, 1),
"optimeDate" : ISODate("2015-10-01T10:16:23Z"),
"syncingTo" : "42.96.194.60:27017",
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "42.96.194.60:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 66,
"optime" : Timestamp(1443694583, 1),
"optimeDate" : ISODate("2015-10-01T10:16:23Z"),
"lastHeartbeat" : ISODate("2015-10-01T10:21:53.026Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T10:21:52.588Z"),
"pingMs" : 16,
"electionTime" : Timestamp(1443694079, 1),
"electionDate" : ISODate("2015-10-01T10:07:59Z"),
"configVersion" : 1
},
{
"_id" : 2,
"name" : "45.63.50.67:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 66,
"optime" : Timestamp(1443694583, 1),
"optimeDate" : ISODate("2015-10-01T10:16:23Z"),
"lastHeartbeat" : ISODate("2015-10-01T10:21:51.818Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T10:21:53.006Z"),
"pingMs" : 311,
"syncingTo" : "42.96.194.60:27017",
"configVersion" : 1
}
],
"ok" : 1
}
CoamReSet:SECONDARY> exit
bye
登录到 42.96.194.60 Primary 节点,通过 rs.remove() 方法来删除副本集中的某一个节点,这里我们还是将 43.241.222.110 删除.删除之后我们还往 42.96.194.60 主节点中加入数据.
CoamReSet:PRIMARY> rs.remove("43.241.222.110:27017")
{ "ok" : 1 }
CoamReSet:PRIMARY> rs.status()
{
"set" : "CoamReSet",
"date" : ISODate("2015-10-01T10:24:35.061Z"),
"myState" : 1,
"members" : [
{
"_id" : 1,
"name" : "42.96.194.60:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2455,
"optime" : Timestamp(1443695065, 1),
"optimeDate" : ISODate("2015-10-01T10:24:25Z"),
"electionTime" : Timestamp(1443694079, 1),
"electionDate" : ISODate("2015-10-01T10:07:59Z"),
"configVersion" : 2,
"self" : true
},
{
"_id" : 2,
"name" : "45.63.50.67:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2358,
"optime" : Timestamp(1443695065, 1),
"optimeDate" : ISODate("2015-10-01T10:24:25Z"),
"lastHeartbeat" : ISODate("2015-10-01T10:24:33.256Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T10:24:34.102Z"),
"pingMs" : 334,
"configVersion" : 2
}
],
"ok" : 1
}
CoamReSet:PRIMARY> db.guids.find()
{ "_id" : ObjectId("560d03099548a3e5bb8b03bf"), "name" : "replica set", "author" : "webinglin" }
CoamReSet:PRIMARY> db.guids.insert({"name":"remove one node dync"})
WriteResult({ "nInserted" : 1 })
CoamReSet:PRIMARY> db.guids.find()
{ "_id" : ObjectId("560d03099548a3e5bb8b03bf"), "name" : "replica set", "author" : "webinglin" }
{ "_id" : ObjectId("560d0a1d7d9deef6a0890b1f"), "name" : "remove one node dync" }
CoamReSet:PRIMARY> exit
bye
删除 43.241.222.110 节点后,我们往 Primary 节点中加入了新的数据,然后先不要将 43.241.222.110 的 mongod 服务停掉,我们通过mongo连接到 43.241.222.110 的mongod服务来查看数据
root@ubuntu:~# mongo --host 43.241.222.110
> db.guids.find()
{ "_id" : ObjectId("560d03099548a3e5bb8b03bf"), "name" : "replica set", "author" : "webinglin" }
> exit
bye
实验结果可以知道,我们在 45.63.50.67 新加入的数据 {name:”remove one node dync”} 并没有同步到43.241.222.110(已从副本集中删除).
为了让实验结果更加确切,我们查看 43.241.222.110 是否有同步了数据:
root@ubuntu:~# mongo –host 45.63.50.67
CoamReSet:SECONDARY> db.guids.find()
{ “_id” : ObjectId(“557780ebd147e9391020860d”), “name” : “replica set”, “author” : “webinglin” }
{ “_id” : ObjectId(“557785bcbb56172c8e069341”), “name” : “remove one node dync” }
CoamReSet:SECONDARY> exit
bye
实验数据可以看到, 45.63.50.67 同步了在 42.96.194.60 主节点中新增的文档 {“name”:”remove one node dync”},这样就证明了动态删除副本集中的某一个节点的实验成功了.那怎么动态添加节点到副本集中呢?
原理是一样的,但是调用的方法变成了 rs.add(“43.241.222.110:27017”)
CoamReSet:PRIMARY> rs.add("43.241.222.110:27017");
{ "ok" : 1 }
CoamReSet:PRIMARY> rs.status()
{
"set" : "CoamReSet",
"date" : ISODate("2015-10-01T10:32:45.284Z"),
"myState" : 1,
"members" : [
{
"_id" : 1,
"name" : "42.96.194.60:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2945,
"optime" : Timestamp(1443695560, 1),
"optimeDate" : ISODate("2015-10-01T10:32:40Z"),
"electionTime" : Timestamp(1443694079, 1),
"electionDate" : ISODate("2015-10-01T10:07:59Z"),
"configVersion" : 3,
"self" : true
},
{
"_id" : 2,
"name" : "45.63.50.67:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2849,
"optime" : Timestamp(1443695560, 1),
"optimeDate" : ISODate("2015-10-01T10:32:40Z"),
"lastHeartbeat" : ISODate("2015-10-01T10:32:43.660Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T10:32:44.079Z"),
"pingMs" : 452,
"syncingTo" : "42.96.194.60:27017",
"configVersion" : 2
},
{
"_id" : 3,
"name" : "43.241.222.110:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2,
"optime" : Timestamp(1443695560, 1),
"optimeDate" : ISODate("2015-10-01T10:32:40Z"),
"lastHeartbeat" : ISODate("2015-10-01T10:32:44.739Z"),
"lastHeartbeatRecv" : ISODate("2015-10-01T10:32:43.300Z"),
"pingMs" : 16,
"syncingTo" : "42.96.194.60:27017",
"configVersion" : 3
}
],
"ok" : 1
}
CoamReSet:PRIMARY> exit
bye
在rs.status()返回的结果中可以看到,43.241.222.110 节点已经成功加入副本集中了.加入之后,理论上应该会把在 43.241.222.110 主节点加入的数据同步过来,刚才删除之后是不会同步的.那这时候重新加入副本集,应该是要同步的.下面是实验结果:
root@ubuntu:~# mongo
CoamReSet:SECONDARY> db.guids.find()
{ "_id" : ObjectId("560d03099548a3e5bb8b03bf"), "name" : "replica set", "author" : "webinglin" }
{ "_id" : ObjectId("560d0a1d7d9deef6a0890b1f"), "name" : "remove one node dync" }
CoamReSet:SECONDARY> exit
bye
实验结果显示,动态添加操作也正常.动态的将 43.241.222.110 节点加入到副本集中能够保证数据同步成功.
注意
在调用 rs.add(“host:ip”) 或者 rs.remove(“host:ip”) 的时候,必须要在 Primary 节点中进行.
add方法可以加入一个document对象,这样就可以在指定具体的Secondary节点的更多的设置项了,比如指定为priority: 0 或 priority: 0,hidden: true 或 priority:0,hidden:true,arbiterOnly:true
{
_id: <int>,
host: <string>,
arbiterOnly: <boolean>,
buildIndexes: <boolean>,
hidden: <boolean>,
priority: <number>,
tags: <document>,
slaveDelay: <int>,
votes: <number>
}
怎么对副本集进行权限验证,参考主从复制的安全部分,也是通过openssl来生成keyfile,然后再启动mongod的时候指定keyFile来设置安全的
也可以在三个主机的复制集添加以下配置
replication:
##oplog大小
oplogSizeMB: 20
##复制集名称
replSetName: CoamReSet
复制集优先级问题
默认设定节点 43.241.222.110 为Primary主节点,由于初始配置中没有设定,于是在主节点服务器重启后 43.241.222.110 自动切换成 从节点,而 42.96.194.60 切换成了主节点导致应用程序连接错误
于是在当前主节点 43.241.222.110 通过命令行手动切换主节点到 43.241.222.110
CoamReSet:PRIMARY> rs.status()
{
"set" : "CoamReSet",
"date" : ISODate("2015-10-09T11:28:28.585Z"),
"myState" : 1,
"members" : [
{
"_id" : 1,
"name" : "42.96.194.60:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 614570,
"optime" : Timestamp(1444378212, 1),
"optimeDate" : ISODate("2015-10-09T08:10:12Z"),
"electionTime" : Timestamp(1444378334, 1),
"electionDate" : ISODate("2015-10-09T08:12:14Z"),
"configVersion" : 3,
"self" : true
},
{
"_id" : 2,
"name" : "45.63.50.67:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : Timestamp(0, 0),
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2015-10-09T11:28:27.754Z"),
"lastHeartbeatRecv" : ISODate("2015-10-06T08:52:51.239Z"),
"pingMs" : 406,
"lastHeartbeatMessage" : "Failed attempt to connect to 45.63.50.67:27017; couldn't connect to server 45.63.50.67:27017 (45.63.50.67), connection attempt failed",
"configVersion" : -1
},
{
"_id" : 3,
"name" : "43.241.222.110:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 90994,
"optime" : Timestamp(1444378212, 1),
"optimeDate" : ISODate("2015-10-09T08:10:12Z"),
"lastHeartbeat" : ISODate("2015-10-09T11:28:27.532Z"),
"lastHeartbeatRecv" : ISODate("2015-10-09T11:28:27.299Z"),
"pingMs" : 15,
"configVersion" : 3
}
],
"ok" : 1
}
CoamReSet:PRIMARY> config = rs.conf()
{
"_id" : "CoamReSet",
"version" : 3,
"members" : [
{
"_id" : 1,
"host" : "42.96.194.60:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 2,
"host" : "45.63.50.67:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 3,
"host" : "43.241.222.110:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatTimeoutSecs" : 10,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
}
}
}
设置第一个节点 42.96.194.60 优先级为1,第二个节点 45.63.50.67 优先级为0,第三个节点 43.241.222.110 优先级为2;
CoamReSet:PRIMARY> config.members[0].priority = 1
1
CoamReSet:PRIMARY> config.members[1].priority = 0
0
CoamReSet:PRIMARY> config.members[2].priority = 2
2
CoamReSet:PRIMARY> rs.reconfig(config)
{ "ok" : 1 }
CoamReSet:PRIMARY> rs.status()
{
"set" : "CoamReSet",
"date" : ISODate("2015-10-09T12:03:37.679Z"),
"myState" : 2,
"syncingTo" : "43.241.222.110:27017",
"members" : [
{
"_id" : 1,
"name" : "42.96.194.60:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 616679,
"optime" : Timestamp(1444392119, 1),
"optimeDate" : ISODate("2015-10-09T12:01:59Z"),
"syncingTo" : "43.241.222.110:27017",
"configVersion" : 5,
"self" : true
},
{
"_id" : 2,
"name" : "45.63.50.67:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : Timestamp(0, 0),
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2015-10-09T12:03:35.875Z"),
"lastHeartbeatRecv" : ISODate("2015-10-06T08:52:51.239Z"),
"pingMs" : 406,
"lastHeartbeatMessage" : "Failed attempt to connect to 45.63.50.67:27017; couldn't connect to server 45.63.50.67:27017 (45.63.50.67), connection attempt failed",
"configVersion" : -1
},
{
"_id" : 3,
"name" : "43.241.222.110:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 93103,
"optime" : Timestamp(1444392119, 1),
"optimeDate" : ISODate("2015-10-09T12:01:59Z"),
"lastHeartbeat" : ISODate("2015-10-09T12:03:35.817Z"),
"lastHeartbeatRecv" : ISODate("2015-10-09T12:03:36.764Z"),
"pingMs" : 17,
"electionTime" : Timestamp(1444390463, 1),
"electionDate" : ISODate("2015-10-09T11:34:23Z"),
"configVersion" : 5
}
],
"ok" : 1
}
可以看到 43.241.222.110 已经成功切换成主节点了
关闭主节点 43.241.222.110 后,发现两个从节点没有自动切换成主节点,相当于关闭了 MongoDB 复制集功能
MongoDB RS优先级设置
http://docs.mongodb.org/manual/tutorial/force-member-to-be-primary/
问题解决
主节点 43.241.222.110 服务意外停止后,在从节点 42.96.194.60 修改优先级出现如下错误
1 | CoamReSet:RECOVERING> config = rs.conf(); |