副本集(replica set)是 MongoDB 的一种集群复制方式,它是一组服务器,其中有一个主服务器(primary),用于处理客户端气请求;还有多个备份服务器(secondary),用于保存主服务器的数据副本。如果主服务器下线了,备份服务器会自动提升一个成员为主服务器。

本文将使用3台 CentOS 系统,以 yum 安装的 MongoDB 服务为例,讲解副本集的创建。

  • 10.171.5.172:27017
  • 10.171.5.173:27017
  • 10.171.5.174:27017

安装MongoDB

安装很简单,通过 yum 即可。

yum install mongodb mongodb-server -y
chkconfig mongod on
service mongod start

调整配置文件

通过 yum 安装的 MongoDB 配置文件位于 /etc/mongodb.conf,我们需要修改 bind_ipreplSet

bind_ip 是监听 ip ,默认是 127.0.0.1 为了多个节点能够互相通信,我们可以将其改为网卡 ip ,或直接改为 0.0.0.0,监听所有 ip。

bind_ip = 0.0.0.0

replSet 是副本集的标识符,可以自定义,所有节点必须相同

replSet = qiansw

修改完成后重启 MongoDB。

service mongod restart

创建副本集

首先根据节点的 ip 和端口确定我们的配置,在 mongo shell 中执行。

config = {
    "_id" : "qiansw",
    "members" : [
        {
            "_id" : 0,
            "host" : "10.171.5.172:27017"
        },
        {
            "_id" : 1,
            "host" : "10.171.5.173:27017"
        },
        {
            "_id" : 2,
            "host" : "10.171.5.174:27017"
        }
    ]
}

这个配置文档中有几个重要的部分。"_id" 字段的值就是启动时从配置文件传递进来的副本集名称(在本例中是 “qiansw”)。一定要保证这个名称与配置文件中的相同。

这个文档的剩余部分是一个副本集成员数组。其中每个元素都需要两个字段:一个唯一的数值类型的 “_id” 字段,和一个主机名(将例子中的主机名替换为你自己实际使用的主机地址和端口)。

然后执行 rs.initiate(config) 初始化副本集。

> rs.initiate(config)
{
    "info" : "Config now saved locally.  Should come online in about a minute.",
    "ok" : 1
}

这台节点服务器会解析这个配置对象,然后想其他成员发送消息,提醒他们使用心得配置。所有成员都配置完成之后,它们会自动选出一个主节点,然后就可以正常处理读写请求了。

副本集创建成功后,shell 中会显示副本集的标识符和它的身份。

mongo副本集.jpg

加入新节点

我们的新节点为 10.171.5.175:27017,只要在主节点执行 rs.add("10.171.5.175:27017") 即可,成功的话会有返回消息。

qiansw:PRIMARY> rs.add("10.171.5.175:27017")
{ "down" : [ "10.171.5.175:27017" ], "ok" : 1 }

查看副本集状态

可以通过 rs.status() 查看副本集的状态。

qiansw:PRIMARY> rs.status()
{
    "set" : "qiansw",
    "date" : ISODate("2016-12-02T02:00:11Z"),
    "myState" : 1,
    "members" : [
        {
            "_id" : 0,
            "name" : "10.171.5.172:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 475,
            "optime" : Timestamp(1480643825, 1),
            "optimeDate" : ISODate("2016-12-02T01:57:05Z"),
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "10.171.5.173:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 425,
            "optime" : Timestamp(1480643825, 1),
            "optimeDate" : ISODate("2016-12-02T01:57:05Z"),
            "lastHeartbeat" : ISODate("2016-12-02T02:00:10Z"),
            "lastHeartbeatRecv" : ISODate("2016-12-02T02:00:10Z"),
            "pingMs" : 0,
            "syncingTo" : "10.171.5.172:27017"
        },
        {
            "_id" : 2,
            "name" : "10.171.5.174:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 423,
            "optime" : Timestamp(1480643825, 1),
            "optimeDate" : ISODate("2016-12-02T01:57:05Z"),
            "lastHeartbeat" : ISODate("2016-12-02T02:00:10Z"),
            "lastHeartbeatRecv" : ISODate("2016-12-02T02:00:10Z"),
            "pingMs" : 0,
            "syncingTo" : "10.171.5.172:27017"
        },
        {
            "_id" : 3,
            "name" : "10.171.5.175:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 186,
            "optime" : Timestamp(1480643825, 1),
            "optimeDate" : ISODate("2016-12-02T01:57:05Z"),
            "lastHeartbeat" : ISODate("2016-12-02T02:00:09Z"),
            "lastHeartbeatRecv" : ISODate("2016-12-02T02:00:09Z"),
            "pingMs" : 0,
            "syncingTo" : "10.171.5.172:27017"
        }
    ],
    "ok" : 1
}

您还可以通过 rs.help() 查看其它可使用的命令。

副本集的所有配置都会保存在 local 数据库中,重启后会自动竞选一个主节点。