MongoDB复制集是一个带有故障转移的主从集群。是从现有的主从模式演变而来,增长了自动故障转移和节点成员自动恢复。MongoDB复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举产生一个主结点。该主结点被称为primary,一个或多个从结点被称为secondaries。primary结点基本上就是master结点,不一样之处在于primary结点在不一样时间多是不一样的服务器。若是当前的主结点失效了,复制集中的其他结点将会试图选出一个新的主结点。linux
MongoDB复制集模式的好处:mongodb
在一个MongoDB复制集集群中,各个服务器有如下几种状态:shell
如上介绍所知,mongodb中的复制能够在多台服务器中同步数据。复制提供了冗余和增长了数据的高可用性,防止单个节点易丢失数据的可能性,也能够用来进行读写分离提升客户端操做性能。复制集中各节点的mongodb实例有相同的数据集副本。主节点能够接收客户端全部写操做记录到日志中,从库复制主库的操做日志记录应用到其数据库中。一个客户端只能有一个主节点,若是主节点不可用(10秒内没法链接),复制集中将选一个成员节点做为主节点。数据库
MongoDB主备+仲裁的基本结构以下:vim
主节点(Primary)
在复制集中,主节点是惟一可以接收写请求的节点。MongoDB在主节点进行写操做,并将这些操做记录到主节点的oplog中。而从节点将会从oplog复制到其本机,并将这些操做应用到本身的数据集上。(复制集最多只能拥有一个主节点)
从节点(Secondaries)
从节点经过应用主节点传来的数据变更操做来保持其数据集与主节点一致。从节点也能够经过增长额外参数配置来对应特殊需求。例如,从节点能够是non-voting或是priority 0.
仲裁节点(ARBITER)
仲裁节点即投票节点,其自己并不包含数据集,且也没法晋升为主节点。可是,旦当前的主节点不可用时,投票节点就会参与到新的主节点选举的投票中。仲裁节点使用最小的资源而且不要求硬件设备。投票节点的存在使得复制集能够以偶数个节点存在,而无需为复制集再新增节点 不要将投票节点运行在复制集的主节点或从节点机器上。 投票节点与其余 复制集节点的交流仅有:选举过程当中的投票,心跳检测和配置数据。这些交互都是不加密的。bash
心跳检测
复制集成员每两秒向复制集中其余成员进行心跳检测。若是某个节点在10秒内没有返回,那么它将被标记为不可用。服务器
MongoDB副本集是有故障恢复功能的主从集群,由一个primary节点和一个或多个secondary节点组成:
节点同步过程: Primary节点写入数据,Secondary经过读取Primary的oplog获得复制信息,开始复制数据而且将复制信息写入到本身的oplog。若是某个操做失败,则备份节点中止从当前数据源复制数据。若是某个备份节点因为某些缘由挂掉了,当从新启动后,就会自动从oplog的最后一个操做开始同步,同步完成后,将信息写入本身的oplog,因为复制操做是先复制数据,复制完成后再写入oplog,有可能相同的操做会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操做执行屡次,与执行一次的效果是同样的。app
通俗理解:当Primary节点完成数据操做后,Secondary会作出一系列的动做保证数据的同步:
- 检查本身local库的oplog.rs集合,找出最近的时间戳。
- 检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。
- 将找到的记录插入到本身的oplog.rs集合中,并执行这些操做。dom
副本集的同步和主从同步同样,都是异步同步的过程,不一样的是副本集有个自动故障转移的功能。其原理是:slave端从primary端获取日志,而后在本身身上彻底顺序的执行日志所记录的各类操做(该日志是不记录查询操做的),这个日志就是local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小能够在启动参数中设 定:–oplogSize 1000,单位是M。异步
注意:在副本集的环境中,要是全部的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。
下面简单介绍下MongoDB 副本集的部署过程:
1)服务器信息 sign-mongo01.wangshibo.cn 172.16.51.216 Primary sign-mongo02.wangshibo.cn 172.16.51.217 Secondary sign-mongo03.wangshibo.cn 172.16.51.218 Arbiter 三台服务器均设置好主机名,关闭iptables及selinux(略) 2)在3台服务器文件hosts文件中都添加如下3行: [root@sign-mongo01 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.16.51.216 sign-mongo01.wangshibo.cn 172.16.51.217 sign-mongo02.wangshibo.cn 172.16.51.218 sign-mongo03.wangshibo.cn 3)安装部署mongodb(三台机器都安装) 下载地址:https://www.mongodb.org/dl/linux/x86_64-rhel62 [app@sign-mongo01 software]$ pwd /data/software [app@sign-mongo01 software]$ ls mongodb-linux-x86_64-rhel62-v3.2-latest.tgz [app@sign-mongo01 software]$ tar -zvxf mongodb-linux-x86_64-rhel62-v3.2-latest.tgz [app@sign-mongo01 software]$ mv mongodb-linux-x86_64-rhel62-3.2.17-34-g4c1bae566c /data/mongodb [app@sign-mongo01 software]$ cd /data/mongodb/ [app@sign-mongo01 mongodb]$ mkdir data [app@sign-mongo01 mongodb]$ mkdir log [app@sign-mongo01 mongodb]$ vim mongodb.conf pidfilepath=/data/mongodb/log/mongod.pid logpath=/data/mongodb/log/mongod.log dbpath=/data/mongodb logappend=true bind_ip=172.16.51.216 port=27017 fork=true replSet=rs0 备节点的mongodb.conf配置文件分别为: [app@sign-mongo02 mongodb]$ vim mongodb.conf pidfilepath=/data/mongodb/log/mongod.pid logpath=/data/mongodb/log/mongod.log dbpath=/data/mongodb logappend=true bind_ip=172.16.51.217 port=27018 fork=true replSet=rs0 其中:replSet=rs0 #表示复制集名称:rs0 启动主备服务器的mongodb [app@sign-mongo01 ~]$ /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf about to fork child process, waiting until server is ready for connections. forked process: 7317 child process started successfully, parent exiting [app@sign-mongo01 mongodb]$ ps -ef|grep mongodb app 7317 1 0 21:38 ? 00:00:00 /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf app 7342 7254 0 21:38 pts/1 00:00:00 grep mongodb [app@sign-mongo01 mongodb]$ lsof -i:27017 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mongod 7317 app 6u IPv4 27011 0t0 TCP sign-mongo01.wangshibo.cn:27017 (LISTEN) [app@sign-mongo02 mongodb]$ /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf about to fork child process, waiting until server is ready for connections. forked process: 9725 child process started successfully, parent exiting [app@sign-mongo02 mongodb]$ lsof -i:27018 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mongod 9725 app 6u IPv4 27191 0t0 TCP sign-mongo02.wangshibo.cn:27018 (LISTEN) 设置mongodb的环变量 [root@sign-mongo01 src]# vim /etc/profile ...... export PATH=$PATH:/data/mongodb/bin [root@sign-mongo01 src]# source /etc/profile 登陆到mongodb中: [app@sign-mongo01 ~]$ mongo 172.16.51.216:27017 MongoDB shell version: 3.2.17-34-g4c1bae566c connecting to: 172.16.51.216:27017/test Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see http://docs.mongodb.org/ Questions? Try the support group http://groups.google.com/group/mongodb-user Server has startup warnings: 2017-11-22T21:38:18.063+0800 I CONTROL [initandlisten] 2017-11-22T21:38:18.063+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-11-22T21:38:18.063+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:38:18.063+0800 I CONTROL [initandlisten] 2017-11-22T21:38:18.063+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-11-22T21:38:18.063+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:38:18.063+0800 I CONTROL [initandlisten] > 初始化复制集:(集合为:"rs0" ;第一个成员为:"sign-mongo01.wangshibo.cn:27017" > rs.initiate({_id: "rs0",members: [{ _id: 0 , host: "sign-mongo01.wangshibo.cn:27017" }]}) { "ok" : 1 } rs0:OTHER> //接着回车,显示这个节点为Primary主节点 rs0:PRIMARY> 接着添加另1个成员: rs0:PRIMARY> rs.add("sign-mongo02.wangshibo.cn:27018") { "ok" : 1 } 查当作员信息 (或者使用 db.isMaster() ) rs0:PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2017-11-22T13:55:28.446Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "sign-mongo01.wangshibo.cn:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1031, "optime" : { "ts" : Timestamp(1511358895, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-22T13:54:55Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1511358843, 2), "electionDate" : ISODate("2017-11-22T13:54:03Z"), "configVersion" : 2, "self" : true }, { "_id" : 1, "name" : "sign-mongo02.wangshibo.cn:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 32, "optime" : { "ts" : Timestamp(1511358895, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-22T13:54:55Z"), "lastHeartbeat" : ISODate("2017-11-22T13:55:27.684Z"), "lastHeartbeatRecv" : ISODate("2017-11-22T13:55:27.827Z"), "pingMs" : NumberLong(0), "configVersion" : 2 } ], "ok" : 1 } 或者使用该方法查看,结果也是同样: rs0:PRIMARY> use admin switched to db admin rs0:PRIMARY> db.runCommand( { replSetGetStatus : 1 } ) { "set" : "rs0", "date" : ISODate("2017-11-23T01:12:20.701Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "sign-mongo01.wangshibo.cn:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 41643, "optime" : { "ts" : Timestamp(1511358895, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-22T13:54:55Z"), "electionTime" : Timestamp(1511358843, 2), "electionDate" : ISODate("2017-11-22T13:54:03Z"), "configVersion" : 2, "self" : true }, { "_id" : 1, "name" : "sign-mongo02.wangshibo.cn:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 40645, "optime" : { "ts" : Timestamp(1511358895, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-22T13:54:55Z"), "lastHeartbeat" : ISODate("2017-11-23T01:12:19.418Z"), "lastHeartbeatRecv" : ISODate("2017-11-23T01:12:16.225Z"), "pingMs" : NumberLong(0), "configVersion" : 2 } ], "ok" : 1 } rs0:PRIMARY> 详细说明以下: "_id" : #集群中节点编号 "name" : #成员服务器名称及端口 "health" : #表示成员中的健康状态(0:down;1:up) "state" : #为0~10,表示成员的当前状态 "stateStr" : #描述该成员是主库(PRIMARY)仍是备库(SECONDARY) "uptime" : #该成员在线时间(秒) "optime" : #成员最后一次应用日志(oplog)的信息 "optimeDate" : #成员最后一次应用日志(oplog)的时间 "electionTime" : #当前primary从操做日志中选举信息 "electionDate" : #当前primary被选定为primary的日期 "configVersion" : #mongodb版本 "self" : #为true 表示当前节点 4)测试操做。在主库中,能够任意操做: rs0:PRIMARY> show dbs local 0.000GB rs0:PRIMARY> use mydb //切换到要建立的数据库 switched to db mydb rs0:PRIMARY> show dbs //use只是转到相关数据库,此时并无作任何操做,因此并不会建立相应的数据库,只有当真正的操做了一次数据库就会自动建立。 local 0.000GB rs0:PRIMARY> db.stats(); { "db" : "mydb", "collections" : 0, "objects" : 0, "avgObjSize" : 0, "dataSize" : 0, "storageSize" : 0, "numExtents" : 0, "indexes" : 0, "indexSize" : 0, "fileSize" : 0, "ok" : 1 } rs0:PRIMARY> db.coll.insert({"id":1}) WriteResult({ "nInserted" : 1 }) rs0:PRIMARY> db.coll.find() { "_id" : ObjectId("5a162222991b83743942d169"), "id" : 1 } rs0:PRIMARY> db.coll.remove({"id":1}) WriteResult({ "nRemoved" : 1 }) rs0:PRIMARY> show dbs local 0.000GB mydb 0.000GB 如今到备库中 172.16.51.217 (sign-mongo02.wangshibo.cn ) 查看分库数据库目录,发现多了数据库,数据库与主库(172.16.51.216)一致!是主库同步过来的。 [app@sign-mongo02 ~]$ mongo 172.16.51.217:27018 MongoDB shell version: 3.2.17-34-g4c1bae566c connecting to: 172.16.51.217:27018/test Server has startup warnings: 2017-11-22T21:46:38.417+0800 I CONTROL [initandlisten] 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] 在副本服务器中登陆其本地数据库,发现能够链接,可是没法读写操做: rs0:SECONDARY> show dbs 2017-11-23T09:25:35.961+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:781:19 shellHelper@src/mongo/shell/utils.js:671:15 @(shellhelp2):1:1 rs0:SECONDARY> 从库开启读操做(此时能够测试主库插入,从库查看,同步正常): rs0:SECONDARY> rs.slaveOk(); rs0:SECONDARY> show dbs local 0.000GB mydb 0.000GB 5)如今模拟主库不可用,将主节点服务中止: [app@sign-mongo01 mongodb]$ pkill -9 mongod [app@sign-mongo01 mongodb]$ ps -ef|grep mongodb app 9524 9398 0 09:32 pts/0 00:00:00 grep mongodb 到备节点172.16.51.217 中登陆mongodb,查看复制集状态: [app@sign-mongo02 ~]$ mongo 172.16.51.217:27018 MongoDB shell version: 3.2.17-34-g4c1bae566c connecting to: 172.16.51.217:27018/test Server has startup warnings: 2017-11-22T21:46:38.417+0800 I CONTROL [initandlisten] 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] rs0:SECONDARY> rs.status() { "set" : "rs0", "date" : ISODate("2017-11-23T01:33:29.688Z"), "myState" : 2, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "sign-mongo01.wangshibo.cn:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2017-11-23T01:33:28.732Z"), "lastHeartbeatRecv" : ISODate("2017-11-23T01:32:28.099Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 1, "name" : "sign-mongo02.wangshibo.cn:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 42412, "optime" : { "ts" : Timestamp(1511399985, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-11-23T01:19:45Z"), "infoMessage" : "could not find member to sync from", "configVersion" : 2, "self" : true } ], "ok" : 1 } 有上面可看出,主节点删除服务进程,primary并无切换到备节点上: 再次启动主节点的mongodb服务,发现primary才自动切换回到主节点: [app@sign-mongo01 mongodb]$ nohup /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf nohup: ignoring input and appending output to `nohup.out' [app@sign-mongo01 mongodb]$ ps -ef|grep mongodb app 9538 1 8 09:37 ? 00:00:00 /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf app 9610 9398 0 09:37 pts/0 00:00:00 grep mongodb [app@sign-mongo01 mongodb]$ mongo 172.16.51.216:27017 MongoDB shell version: 3.2.17-34-g4c1bae566c connecting to: 172.16.51.216:27017/test Server has startup warnings: 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] rs0:PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2017-11-23T01:38:19.631Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "sign-mongo01.wangshibo.cn:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 54, "optime" : { "ts" : Timestamp(1511401058, 2), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-11-23T01:37:38Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1511401058, 1), "electionDate" : ISODate("2017-11-23T01:37:38Z"), "configVersion" : 2, "self" : true }, { "_id" : 1, "name" : "sign-mongo02.wangshibo.cn:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 53, "optime" : { "ts" : Timestamp(1511401058, 2), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-11-23T01:37:38Z"), "lastHeartbeat" : ISODate("2017-11-23T01:38:18.072Z"), "lastHeartbeatRecv" : ISODate("2017-11-23T01:38:18.596Z"), "pingMs" : NumberLong(0), "syncingTo" : "sign-mongo01.wangshibo.cn:27017", "configVersion" : 2 } ], "ok" : 1 } +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 如今开始部署仲裁节点sign-mongo03.wangshibo.cn [app@sign-mongo03 ~]$ mkdir /data/mongodb/arbiter [app@sign-mongo03 ~]$ ll -d /data/mongodb/arbiter drwxrwxr-x 2 app app 4096 Nov 23 09:39 /data/mongodb/arbiter 本案例是在普通用户app帐号下部署的,权限都是app.app。 若是是在root帐号下部署,那么须要将mongodb数据目录下的文件所有设置mongodb.mongodb权限 mongodb.conf配置: [app@sign-mongo03 ~]$ vim /data/mongodb/mongodb.conf pidfilepath=/data/mongodb/log/mongod.pid logpath=/data/mongodb/log/mongod.log dbpath=/data/mongodb/arbiter logappend=false bind_ip=172.16.51.218 port=27019 fork=true replSet=rs0 接着重启服务: [app@sign-mongo03 ~]$ /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf about to fork child process, waiting until server is ready for connections. forked process: 9217 child process started successfully, parent exiting [app@sign-mongo03 ~]$ ps -ef|grep mongo app 9217 1 1 09:46 ? 00:00:00 /data/mongodb/bin/mongod --config /data/mongodb/mongodb.conf app 9242 9158 0 09:46 pts/0 00:00:00 grep mongo [app@sign-mongo03 ~]$ lsof -i:27019 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mongod 9217 app 6u IPv4 37321 0t0 TCP sign-mongo03.wangshibo.cn:27019 (LISTEN) 而后在Paimary主节点sign-mongo01.wangshibo.cn的mongodb中添加仲裁节点并查看结果 [app@sign-mongo01 mongodb]$ mongo 172.16.51.216:27017 MongoDB shell version: 3.2.17-34-g4c1bae566c connecting to: 172.16.51.216:27017/test Server has startup warnings: 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-23T09:37:26.467+0800 I CONTROL [initandlisten] rs0:PRIMARY> rs.addArb("sign-mongo03.wangshibo.cn:27019") { "ok" : 1 } rs0:PRIMARY> db.isMaster() { "hosts" : [ "sign-mongo01.wangshibo.cn:27017", "sign-mongo02.wangshibo.cn:27018" ], "arbiters" : [ "sign-mongo03.wangshibo.cn:27019" ], "setName" : "rs0", "setVersion" : 4, "ismaster" : true, "secondary" : false, "primary" : "sign-mongo01.wangshibo.cn:27017", "me" : "sign-mongo01.wangshibo.cn:27017", "electionId" : ObjectId("7fffffff0000000000000003"), "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2017-11-23T01:59:03.554Z"), "maxWireVersion" : 4, "minWireVersion" : 0, "ok" : 1 } rs0:PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2017-11-23T02:00:26.312Z"), "myState" : 1, "term" : NumberLong(3), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "sign-mongo01.wangshibo.cn:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 368, "optime" : { "ts" : Timestamp(1511402420, 1), "t" : NumberLong(3) }, "optimeDate" : ISODate("2017-11-23T02:00:20Z"), "electionTime" : Timestamp(1511402069, 1), "electionDate" : ISODate("2017-11-23T01:54:29Z"), "configVersion" : 5, "self" : true }, { "_id" : 1, "name" : "sign-mongo02.wangshibo.cn:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 367, "optime" : { "ts" : Timestamp(1511402420, 1), "t" : NumberLong(3) }, "optimeDate" : ISODate("2017-11-23T02:00:20Z"), "lastHeartbeat" : ISODate("2017-11-23T02:00:26.306Z"), "lastHeartbeatRecv" : ISODate("2017-11-23T02:00:26.309Z"), "pingMs" : NumberLong(0), "syncingTo" : "sign-mongo01.wangshibo.cn:27017", "configVersion" : 5 }, { "_id" : 3, "name" : "sign-mongo03.wangshibo.cn:27019", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 93, "lastHeartbeat" : ISODate("2017-11-23T02:00:26.306Z"), "lastHeartbeatRecv" : ISODate("2017-11-23T02:00:25.306Z"), "pingMs" : NumberLong(0), "configVersion" : 5 } ], "ok" : 1 } 至此,添加完成!! 再次测试主备切换。关闭172.16.51.216(primary)中删除服务进程: [app@sign-mongo01 mongodb]$ pkill -9 mongod [app@sign-mongo01 mongodb]$ ps -ef|grep mongod app 9664 9398 0 09:50 pts/0 00:00:00 grep mongod [app@sign-mongo01 mongodb]$ lsof -i:27017 [app@sign-mongo01 mongodb]$ 而后到172.16.51.217:27018(secondary)查看,发现primary已经切换为172.16.51.217 [app@sign-mongo02 ~]$ mongo 172.16.51.217:27018 MongoDB shell version: 3.2.17-34-g4c1bae566c connecting to: 172.16.51.217:27018/test Server has startup warnings: 2017-11-22T21:46:38.417+0800 I CONTROL [initandlisten] 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-22T21:46:38.418+0800 I CONTROL [initandlisten] rs0:PRIMARY> rs.status() { "set" : "rs0", "date" : ISODate("2017-11-23T02:01:17.762Z"), "myState" : 1, "term" : NumberLong(4), "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "sign-mongo01.wangshibo.cn:27017", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2017-11-23T02:01:17.316Z"), "lastHeartbeatRecv" : ISODate("2017-11-23T02:01:04.327Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 1, "name" : "sign-mongo02.wangshibo.cn:27018", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 44080, "optime" : { "ts" : Timestamp(1511402475, 2), "t" : NumberLong(4) }, "optimeDate" : ISODate("2017-11-23T02:01:15Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1511402475, 1), "electionDate" : ISODate("2017-11-23T02:01:15Z"), "configVersion" : 5, "self" : true }, { "_id" : 3, "name" : "sign-mongo03.wangshibo.cn:27019", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 145, "lastHeartbeat" : ISODate("2017-11-23T02:01:17.315Z"), "lastHeartbeatRecv" : ISODate("2017-11-23T02:01:15.316Z"), "pingMs" : NumberLong(0), "configVersion" : 5 } ], "ok" : 1 } rs0:PRIMARY> show dbs local 0.000GB mydb 0.000GB 有上面信息可知,添加仲裁节点后,primary能正常启动切换了!~ 如今看看arbiter,链接到172.16.51.218:27019 [app@sign-mongo03 ~]$ mongo 172.16.51.218:27019 MongoDB shell version: 3.2.17-34-g4c1bae566c connecting to: 172.16.51.218:27019/test Welcome to the MongoDB shell. For interactive help, type "help". For more comprehensive documentation, see http://docs.mongodb.org/ Questions? Try the support group http://groups.google.com/group/mongodb-user Server has startup warnings: 2017-11-23T09:58:34.978+0800 I CONTROL [initandlisten] 2017-11-23T09:58:34.978+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-11-23T09:58:34.978+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-23T09:58:34.978+0800 I CONTROL [initandlisten] 2017-11-23T09:58:34.978+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-11-23T09:58:34.978+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-11-23T09:58:34.978+0800 I CONTROL [initandlisten] rs0:ARBITER> rs.slaveOk(); rs0:ARBITER> db.isMaster() { "hosts" : [ "sign-mongo01.wangshibo.cn:27017", "sign-mongo02.wangshibo.cn:27018" ], "arbiters" : [ "sign-mongo03.wangshibo.cn:27019" ], "setName" : "rs0", "setVersion" : 5, "ismaster" : false, "secondary" : false, "primary" : "sign-mongo02.wangshibo.cn:27018", "arbiterOnly" : true, "me" : "sign-mongo03.wangshibo.cn:27019", "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2017-11-23T02:03:33.874Z"), "maxWireVersion" : 4, "minWireVersion" : 0, "ok" : 1 } rs0:ARBITER> show dbs local 0.000GB arbiter 最为仲裁者,没有数据副本存储在本地,能读取复制集的信息。 ------------------------------------------------------------------------------------------------- 在primary主库上,建立locs数据库,该库的用户名为locsopr,密码为locsopr@123 [app@sign-mongo02 ~]$ mongo 172.16.51.217:27018 ...... rs0:PRIMARY> use locs switched to db locs rs0:PRIMARY> db.createUser({user:"locsopr",pwd :"locsopr@123",roles:["readWrite"]}) Successfully added user: { "user" : "locsopr", "roles" : [ "readWrite" ] } rs0:PRIMARY> show users; //查看当前库下的用户名 { "_id" : "locs.locsopr", "user" : "locsopr", "db" : "locs", "roles" : [ { "role" : "readWrite", "db" : "locs" } ] } 使用上面的用户登陆primary主库 [app@sign-mongo02 ~]$ mongo 172.16.51.217:27018/locs -ulocsopr -plocsopr@123 ......... rs0:PRIMARY> show users { "_id" : "locs.locsopr", "user" : "locsopr", "db" : "locs", "roles" : [ { "role" : "readWrite", "db" : "locs" } ] } rs0:PRIMARY> show dbs admin 0.000GB local 0.000GB rs0:PRIMARY> 再登陆从库看下: [app@sign-mongo01 ~]$ mongo 172.16.51.216:27017/locs -ulocsopr -plocsopr@123 ....... rs0:SECONDARY> rs.slaveOk(); rs0:SECONDARY> show users { "_id" : "locs.locsopr", "user" : "locsopr", "db" : "locs", "roles" : [ { "role" : "readWrite", "db" : "locs" } ] } rs0:SECONDARY> show dbs admin 0.000GB local 0.000GB
-------------------------------------------------------------------------------------------------------------------------------------------------------
上面介绍的是三台mongodb节点:一主一备一仲裁,这样,主节点挂了后,经过仲裁机制将primary自动切换到备机上!
若是上面的三台mongodb节点:一主两备,没有仲裁节点,那么主节点挂了后,primary会自动切换到其他两台备节点中的一台上!
一主两从(端口分别为2701七、2701八、27019)的mongodb配置和上面一主一从(端口分别为2701七、27018)的配置同样。 多加的一个从节点,在主节点登录mongodb,使用rs.add命令将这个成员加到集群中便可! 一主两从的模式,好比: 主节点sign-mongo01.wangshibo.cn的mongodb服务程序挂了后,另外两个从节点中的一个(好比sign-mongo02.wangshibo.cn)会自动变成primary主节点, 另外一个节点sign-mongo03.wangshibo.cn则是新的主节点(sign-mongo02.wangshibo.cn)的从节点。 ++++++++++++++++++++++++++++++若是想让切换回原来的主节点,作法以下+++++++++++++++++++++++++++++++ 1)恢复原来的主节点sign-mongo01.wangshibo.cn的mongodb服务,使用命令rs.status() 确认数据集成员运行正常。 2)到次节点sign-mongo03.wangshibo.cn中登陆mongodb,运行freeze使其120内不会变为主节点。 > rs.freeze(120) 3) 到新的主节点sign-mongo02.wangshibo.cn中强制切换主节点,stepDown将阻止长事务和写入操做 > rs.stepDown(120) 4)此时sign-mongo01.wangshibo.cn节点变成primary主节点。使用rs.status()命令能够查看到集群状态。 +++++++++++++++++++++++若要使某个节点永远不会变为主节点,设置优先级为0便可+++++++++++++++++++++++ 登录当前主节点的mongodb,执行下面操做: rs0:PRIMARY> cfg = rs.conf() rs0:PRIMARY> cfg.members[0].priority = 0.5 rs0:PRIMARY> cfg.members[1].priority = 0.5 rs0:PRIMARY> cfg.members[2].priority = 0 rs0:PRIMARY> rs.reconfig(cfg) 说明: 其中成员编号0/1/2为 rs.status()中的 "_id"值 members[2]表示sign-mongo03.wangshibo.cn,则它将永远不会变成主节点!由于优先级设置为0了! ++++++++++++++++++++++++++++++++移除一个复制成员(两种方法)++++++++++++++++++++++++++++++++++++ 登录当前主节点的mongodb,执行下面操做: rs0:PRIMARY> rs.remove("sign-mongo03.wangshibo.cn:27019") rs0:PRIMARY> rs.conf() 或者: rs0:PRIMARY> cfg = rs.conf() rs0:PRIMARY> cfg.members.splice(2,1) rs0:PRIMARY> rs.reconfig(cfg) 移除后到移除的节点服务器(即sign-mongo03.wangshibo.cn),更改配置文件mongod.conf #replSet=rs0 //将这一行注释 而后再重启mongodb服务,这就完成了移除(数据库文件仍保留在当前服务器)。