Mongodb 3.4 Replication
基本架构
Replication:主从结构,一个Primary,多个Secondary,可能会有Arbitry(仲裁)。
Primary挂掉之后,会选举出一个Secondary作为Primary,与zookeeper类似。
Arbitry上面不存数据,只是为了凑数。选举算法要求节点数必须是奇数个,如果Primary+Secondary不是奇数个,就要用Arbitry凑数。
写数据只能在Primary,读数据默认也在Primary,可以配置成从Secondary读,可以选最近的节点。
数据在Primary上写成功之后,会将操作记录在oplog中,Secondary将oplog拷贝过去,然后照着操作一遍,就有数据了。
Primary和Secondary上面的数据保证最终一致性,可以为写操作配置write concern,有几个级别:在Primary上写完就认为写成功;写到oplog后认为写成功;写到一个/多个/某个/某几个Secondary之后认为写成功,等等。
基本架构
一个包含3个mongod的复制集架构如下所示:


如果主服务器失效,会变成:


如果主服务器失效:

测试部署过程
我们在同一台机器上部署一个含有3个实例的单机复制集,部署环境centos 7,mongdb版本3.4

查看配置文件:
[root@localhost mongodb]# vim mongo27017/mongo.conf

红框部分是需要增加的内容
参数说明:
oplogSizeMB
数字,复制操作日志的最大大小(M),该mongod过程基于最大可用空间量创建一个oplog,对于64位系统,oplog通常是可用磁盘的5%,一旦mongod第一次创建了oplog,更改replication.oplogSizeMB将不会影响oplog的大小
replSetName
字符,作为其mongod部分副本集的名称,副本集中的所有主机都必须具有相同的名称,如果应用程序连接到多个副本集,则每个集合应具有不同的名称,某些驱动程序组副本通过副本集名称设置连接
secondaryIndexPrefetch
字符,仅适用于mmapv1存储引擎,在从oplog应用操作之前,副本集的辅助成员加载到内存中的索引,默认情况下,在从oplog应用操作之前,二进制文件将与操作相关的所有索引加载到内存中,可选的值有none/all/_id_only,该设置仅适用于mongod
enableMajorityReadConcern
布尔值,默认为False,版本3.2后的新功能
三个实例同样的配置(当然端口不能一样);
启动三个实例:
进入 27017 实例,进入 mongodb
[root@localhost mongodb]# bin/mongo localhost:27017
> use admin; switched to db admin > rs.status(); { "info" : "run rs.initiate(...) if not yet done for the set", "ok" : 0, "errmsg" : "no replset config has been received", "code" : 94, "codeName" : "NotYetInitialized" }
提示要初始化复制集;
> rs.initiate({_id:'demors',members:[{_id:1,host:'192.168.0.15:27017'}]});
demors:OTHER> rs.status();
{
"set" : "demors",
"date" : ISODate("2018-05-02T06:06:51.029Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1525241208, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1525241208, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1525241208, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 1,
"name" : "192.168.0.15:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 260,
"optime" : {
"ts" : Timestamp(1525241208, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-05-02T06:06:48Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1525241206, 2),
"electionDate" : ISODate("2018-05-02T06:06:46Z"),
"configVersion" : 1,
"self" : true
}
],
"ok" : 1
}
demors:PRIMARY>
这时复制集已经可以了,只是现在只有一个成员,并且自动为 PRIMARY
启动另外两个实例,27018和27019,并增加到复制集。
启动完成后,进入 27017 实例
demors:PRIMARY> rs.add("192.168.0.15:27018"); demors:PRIMARY> rs.add("192.168.0.15:27019"); demors:PRIMARY> rs.status(); { "set" : "demors", "date" : ISODate("2018-05-02T08:13:34.131Z"), "myState" : 1, "term" : NumberLong(6), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) }, "appliedOpTime" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) }, "durableOpTime" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) } }, "members" : [ { "_id" : 1, "name" : "192.168.0.15:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 4242, "optime" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) }, "optimeDate" : ISODate("2018-05-02T08:13:24Z"), "electionTime" : Timestamp(1525246052, 1), "electionDate" : ISODate("2018-05-02T07:27:32Z"), "configVersion" : 225726, "self" : true }, { "_id" : 2, "name" : "192.168.0.15:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 2462, "optime" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) }, "optimeDurable" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) }, "optimeDate" : ISODate("2018-05-02T08:13:24Z"), "optimeDurableDate" : ISODate("2018-05-02T08:13:24Z"), "lastHeartbeat" : ISODate("2018-05-02T08:13:32.361Z"), "lastHeartbeatRecv" : ISODate("2018-05-02T08:13:32.232Z"), "pingMs" : NumberLong(0), "syncingTo" : "192.168.0.15:27017", "configVersion" : 225726 }, { "_id" : 3, "name" : "192.168.0.15:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 2462, "optime" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) }, "optimeDurable" : { "ts" : Timestamp(1525248804, 1), "t" : NumberLong(6) }, "optimeDate" : ISODate("2018-05-02T08:13:24Z"), "optimeDurableDate" : ISODate("2018-05-02T08:13:24Z"), "lastHeartbeat" : ISODate("2018-05-02T08:13:32.361Z"), "lastHeartbeatRecv" : ISODate("2018-05-02T08:13:32.232Z"), "pingMs" : NumberLong(0), "syncingTo" : "192.168.0.15:27017", "configVersion" : 225726 } ], "ok" : 1 }
测试复制集
在 PRIMARY(27017) 中插入数据,在 另外两个副本节点(SECONDARY )中也可以看到
如果此时副本节点还无法读取数据,在副本节点设置可读:
demors:SECONDARY> rs.slaveOk();
遇到的问题
1:启动第一个实例是出现如下错误,
[root@localhost mongodb3.4]# bin/mongod -f /usr/local/mongodb3.4/mongo.conf Unrecognized option: replication try 'bin/mongod --help' for more information
配置文件的格式不对,红色间隔不能为 tab, 是两个空格;冒号后不能有空格;

2: 由于配置之前在实例27018中操作过,添加过一些数据,导致添加27018实例到副本集中总数出错
解决方法:分离27018实例,将主节点 27017的数据同步到节点27018中,添加成功。
3:先启动27018实例,在主节点 27017中添加 27018实例,但是失败了,并且节点27018自动挂了,主节点27017自动变为副本节点,
当然这个是27018的数据和主节点27017的数据不同造成的,
解决方法:重新构建复制集,将主节点 27017的数据同步到其他副节点,添加成功
demors:SECONDARY> rs.reconfig({_id:'demors',members:[{_id:1,host:'192.168.0.15:27017'}]});
{
"ok" : 0,
"errmsg" : "replSetReconfig should only be run on PRIMARY, but my state is SECONDARY; use the \"force\" argument to override",
"code" : 10107,
"codeName" : "NotMaster"
}
demors:SECONDARY> rs.reconfig({_id:'demors',members:[{_id:1,host:'192.168.0.15:27017'}]},{ "force": true });
{ "ok" : 1 }
demors:SECONDARY> rs.status();
{
"set" : "demors",
"date" : ISODate("2018-05-02T07:20:04.844Z"),
"myState" : 1,
"term" : NumberLong(4),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1525245600, 1),
"t" : NumberLong(4)
},
"appliedOpTime" : {
"ts" : Timestamp(1525245600, 1),
"t" : NumberLong(4)
},
"durableOpTime" : {
"ts" : Timestamp(1525245600, 1),
"t" : NumberLong(4)
}
},
"members" : [
{
"_id" : 1,
"name" : "192.168.0.15:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1032,
"optime" : {
"ts" : Timestamp(1525245600, 1),
"t" : NumberLong(4)
},
"optimeDate" : ISODate("2018-05-02T07:20:00Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1525245599, 1),
"electionDate" : ISODate("2018-05-02T07:19:59Z"),
"configVersion" : 85482,
"self" : true
}
],
"ok" : 1
}

浙公网安备 33010602011771号