复制介绍

副本集是一组服务器,其中一个主服务器,用于处理客户端请求;还有多个备份服务器,用于保存主服务器的数据副本。如果主服务器崩溃了,备份服务器会自动将其中的一员升级为主服务器。

建立副本集

启动一个不连接到任何 mongod 的 shell

  1. $ mongo --nodb

创建副本集并启动

  1. > replicaSet = new ReplSetTest({"nodes":3}); // 创建副本集
  2. > replicaSet.startSet(); // 启动三个服务器的副本集
  3. > replicaSet.initiate(); // 配置复制功能

自动故障转移,第一个发现主节点挂了的副节点会成为新的主节点。

关闭副本集

> replicaSet.stopSet();

还有几个概念要注意:

  • 客户端在单台服务器上可以执行的请求,都可以到主节点执行(读、写、执行命令、创建索引等)

  • 客户端不能在备份节点上执行写操作

  • 默认情况下,客户端不能从备份节点中读取数据。在备份节点上显示地执行 setSlaveOk 之后,客户端就可以备份解决中读取数据了。

配置副本集

首先为副本集选定名称,选好名称后,重启实例

$ mongod --replSet spock -f mongod.conf --fork

同样的方式启动其他两个 mongod 服务器作为副本,此时每个 mongod 都不知道有其他 mongod 的存在。为了让它们相互之间有联系,需要创建配置文件。

> config = {
    "_id":"spock",
    "members":[
        {"_id":0,"host":"server-1:27017"},
        {"_id":1,"host":"server-2:27017"},
        {"_id":2,"host":"server-3:27017"},
    ]
};

> db = (new Mongo("server-1:27017")).getDB("test"); // 连接到 server-1
> rs.initiate(config); // 初始化副本集

server-1 解析配置对象,然后向其他成员发送消息,提醒他们使用新的配置。所有成员配置完成后,他们会自动选出一个主节点,然后就可以正常处理读写请求了。

修改副本集设置

为副本集添加新成员

> rs.add("server-4:27017");

为副本集删除成员

> rs.remove("server-1:27017");

设计副本集

“大多数”的概念:副本集中一半以上的成员。

推荐的配置方法:

  • 将“大多数”成员放在同一个数据中心。如果有一个数据中心,并且你希望副本集的主节点总是位于主数据中心的话,这样的配置会比较好。只要主数据中心能够正常运转,就会有一个主节点。但是,如果主数据中心不可用了,那么备份数据中心的成员无法选出主节点。

  • 在两个数据中心各自放数量相等的成员,在第三个地方放置一个决定胜负的副本集成员。如果两个数据中心同等重要,那么这种配置会比较好。因为任意一个数据中心的服务器都可以找到另一台服务器达到“大多数”。但是,这样就需要将服务器分散到三个地方。

选举机制

当一个备份节点无法与主节点连通时,它就会联系并请求其它的副本集成员将自己选举为主节点。要求被选举为主节点的成员能够得到副本集中“绝大多数”成员的投票,它就会成为主节点。即时只要一个否决了本次选举,选举就会取消。

成员配置选项

仲裁者

仲裁者的唯一作用是参与选举,它并不保存数据,也不为客户端提供服务,它只是为了帮助具有两个成员的副本集能够满足“大多数”这个条件。

启动仲裁者

> rs.addArb"server-5:27017");

最多只能使用一个仲裁者,仲裁者的出现时为了不出现平票。尽可能在副本集使用奇数个数据成员,尽量不使用仲裁者。

优先级

优先级用于表示一个成员渴望成为主节点的程度,优先级的取值范围可以是0~100,默认是 1。优先级为 0 的成员永远不能成为主节点,这样的成员叫做被动节点。

隐藏成员

客户端不会向隐藏成员发送请求,隐藏成员也不会作为复杂源。因此,很多人会将不够强大的服务器或者备份服务器隐藏起来。

> var config = rs.config();
> config.member[2].hidden = 0;

参考

[1] MongoDB权威指南