MongoDB高可用__使用Replica Set

1. 引言

使用MongoDB,能够以单机模式提供服务。但在实际的生产环境中,单机模式将面临很大的风险,一旦单点数据库服务出现故障,就会致使服务调用出现错误甚至崩溃。所以,在实际生产环境下,须要对MongoDB作相应的主备处理,提升数据库服务的可用性。javascript

对于提升可用性,一些博文里提到了使用主从模式(master-slaver)java

WARNING: Deprecated since version 3.2: MongoDB 3.2 deprecates the use of master-slave replication for components of sharded clusters.mongodb

主从模式是高可用的一种方案。然而上面这段警告里提到,在高版本的MongoDB(3.2以上)的一些场景中,官方已经不推荐使用主从模式,取而代之的,是使用复制集(Replica Set)的方式作主备处理。数据库

IMPORTANT: Replica sets replace master-slave replication for most use cases. If possible, use replica sets rather than master-slave replication for all new production deployments. This documentation remains to support legacy deployments and for archival purposes only.bash

所以,本文将介绍如何将单机MongoDB数据库拓展为主备模式的复制集,以提升可用性。测试

2. 复制集 Replica Set

在复制集中,有且只有一个主节点(primary),能够包含一个或多个从节点(secondary),主从节点经过心跳检测来肯定节点是否健康或存活。全部的读写操做都是在主节点上进行的,若是要实现读写分离,须要进行相应的处理。从节点会根据oplog来复制主节点的数据。url

MongoDB复制集

除了主从节点外,MongoDB的复制集中还存在着一种叫仲裁者(Arbiter)的角色。一个仲裁者节点是比较轻量级的,它不会去复制主库的数据,所以也就不会成为主节点;它是在投票选举阶段起做用的——当主节点故障时,仲裁者能够进行投票。通常来讲,不建议一个复制集中包含超过一个仲裁者。spa

当主节点忽然故障后,MongoDB有本身的机制,会自动切换,经过选举,在从节点中选出一个节点做为新的主节点。日志

MongoDB复制集故障处理

3. 如何使用复制集

3.1. 建立复制集

首先,须要在MongoDB实例的启动参数中加入replSet,指定复制集的名称。code

mongod --port 8017 --dbpath /home/work/data/db1 --replSet rstest
复制代码

对于已有的单机实例,也能够加入该参数并进行重启。此外,咱们还须要另外启动两个MongoDB实例做为从节点,注意replSet参数指定的名称须要相同。

mongod --port 8016 --dbpath /home/work/data/db2 --replSet rstest
mongod --port 8015 --dbpath /home/work/data/db2 --replSet rstest
复制代码

而后,能够经过mongo命令链接MongoDB服务,进入主节点进行初始化。

mongo 127.0.0.1:8017
复制代码
rs.initiate({
  _id:"rstest", // replSet指定的名称
  members:[{
    _id:0,
    host:"127.0.0.1:8017" // 主节点ip与端口
  }]
})
复制代码

须要注意的是,若是是将已有单机拓展为复制集,要在链接原单机的实例并在其中运行使其做为主节点。

最后,再将其余两个从节点加入到该复制集中。

rs.add("127.0.0.1:8016")
rs.add("127.0.0.1:8015")
复制代码

经过rs.status()查看效果,能够看到rstest这个复制集中已经有了三个节点,stateStr指明了节点的类型,health为1代表该节点是健康的。

{
    "set" : "rstest",
    "date" : ISODate("2017-10-31T13:04:16.704Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "127.0.0.1:8017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY", // 节点的类型,主节点
            "uptime" : 1508,
            "optime" : Timestamp(1509455043, 1),
            "optimeDate" : ISODate("2017-10-31T13:04:03Z"),
            "electionTime" : Timestamp(1509454568, 2),
            "electionDate" : ISODate("2017-10-31T12:56:08Z"),
            "configVersion" : 3,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "127.0.0.1:8016",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 25,
            "optime" : Timestamp(1509455043, 1),
            "optimeDate" : ISODate("2017-10-31T13:04:03Z"),
            "lastHeartbeat" : ISODate("2017-10-31T13:04:15.657Z"),
            "lastHeartbeatRecv" : ISODate("2017-10-31T13:04:15.108Z"),
            "pingMs" : 0,
            "syncingTo" : "127.0.0.1:8017",
            "configVersion" : 3
        },
        {
            "_id" : 2,
            "name" : "127.0.0.1:8015",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 13,
            "optime" : Timestamp(1509455043, 1),
            "optimeDate" : ISODate("2017-10-31T13:04:03Z"),
            "lastHeartbeat" : ISODate("2017-10-31T13:04:15.657Z"),
            "lastHeartbeatRecv" : ISODate("2017-10-31T13:04:15.661Z"),
            "pingMs" : 0,
            "configVersion" : 3
        }
    ],
    "ok" : 1
}
复制代码

3.2. 链接复制集

因为复制集存在灾备时中的切换机制,在主节点故障的状况下,集群内其余从节点会经过投票方式产生新的主节点,所以,不能像单机状况下那样,直接链接主节点。不然,在MongoDB复制集中主节点故障,自动切换主节点时,数据库访问就会出问题。所以链接复制集须要特定的链接方式。

在MongoDB的链接字符串(connection url)中能够进行指定。

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
复制代码

其中能够指定多个host:port,用英文逗号链接,并在最后的option中支持replicaSet参数,用于指定链接的复制集。例如:

mongodb://127.0.0.1:8017,127.0.0.1:8016,127.0.0.1:8015/books?replicaSet=rstest
复制代码

这样就能够链接上复制集中的books这个数据库。

4. 总结

MongoDB复制集的故障机制切换是它自身来保障,在部署好上面一系列的服务后,咱们能够测试一下当主节点故障时,集群中的节点状态与服务可用性。

经过kill主节点MongoDB进程,使用rs.status()能够发现,其中一个从节点已经升级为了主节点(这部分在从节点的日志中也有体现)。此外,数据查询依然能够进行,不会由于主节点的宕机而致使数据服务不可用。

相关文章
相关标签/搜索