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
}

 

posted @ 2018-05-02 15:50  南极山  阅读(854)  评论(0)    收藏  举报