复制集

关键概念

  1. 客户端在单台服务器上可以执行的请求,都可以发送到主节点执行。
  2. 客户端不能在备份节点执行写操作。
  3. 默认情况下,客户端不能从备份节点读取数据。需要执行显式执行setSlaveOk.

初始化同步的两种方式

  1. 以空数据目录启动slave服务器
  2. 复制master数据目录到slave,然后启动slave服务器。(需要master停机操作)

将包含数据的单机服务器扩展为复制集(需要停机操作)

假设单机服务器的host为host1,另外两台分别为host2,host3

  • 以复制集的方式启动服务器host1
# 在命令行参数中用--replSet指定复制集名称
/usr/bin/mongod --replSet replName --config /etc/mongod.conf

# 或者在配置文件中增加以下配置
replication:
  replSetName: replName
  • 配置复制集
mongo host1:27017 #连接到服务器
//在mongo shell中执行
var config = {
  _id: 'gpws',
  members: [
    {_id: 0, host: 'host1:27017'},
    {_id: 1, host: 'host2:27017'},
    {_id: 2, host: 'host3:27017'},
  ],
};
rs.initiate(config);
//复制集需要一段时间进行拓扑结构识别,确定主备关系,大概1分钟之内吧
//然后敲回车,就会在提示符中出现replName:PRIMARY>
//host1因为本身包含数据,会成为主库,另外两台会成为备库
//当数据同步全部完成之后,它们的角色可能会再次变动,不过那都已经是复制集内部的事了

选举机制

当一个备份节点无法与主节点连通时,他就会联系并请求其它的副本集成员将自己选举为主节点。其它成员会做几项检查:

  1. 自身是否能够与主节点连通?
  2. 希望被选举为主节点的备份节点的数据是否最新?
  3. 有没有其它更高优先级的成员可以被选举为主节点?

注意:

  • 必须使用mongo shell来配置副本集,没有其它方法可以基于文件对副本集进行配置。
  • 只有达到大多数的情况下才能选举或维持主节点,这样是为了避免出现多个主节点。
  • 尽可能在副本集中使用奇数个数据成员,而不要使用仲裁者。
  • 优先级为0的成员永远不能够成为主节点,这样的成员被称为被动成员(passive member).
  • 隐藏成员{hidden: true}. 客户端不向隐藏成员发送请求。
  • 延迟备份节点{slaveDelay: num},以秒为单位。要求成员的优先级为0. 应该隐藏延迟备份节点,以免读请求被路由到这里。
  • {buildIndexes: false}, 不创建索引。这是一个永久选项,成员永远无法恢复为可以创建索引的正常成员。也要求成员的优先级为0.
  • 修改配置防止复制链的产生,在PRIMARY库的shell中执行以下代码
var config = rs.config();
config.settings.chainingAllowed = false;
rs.reconfig(config);
  • 使slave可读
//解决{"errmsg" : "not master and slaveOk=false", "code" : 13435 }
db.getMongo().setSlaveOk();
  • 关闭主服,用来测试故障转移能否顺利完成
primaryDB.adminCommand({shutdown: 1});
  • rs辅助函数
rs.conf();//当前配置
rs.status();//当前运行状态
rs.reconfig(config);//参数可以是任意合法的配置文档config
rs.add("host:port");//增加成员
rs.remove("host:port");//删除成员

//增加仲裁者 成员一旦以仲裁者的身份添加到副本集中,它就永远只能是仲裁者。
//无法将仲裁者重新配置为非仲裁者,反之亦然。
rs.addArb("host:port");

相关命令使用

# 连接复制集,host部分的参数值格式为replSetName/host1,host2[,...]
mongo --host replSetName/host1,host2 dbname scripts.js
mongoimport -h replSetName/host1,host2 -d dbname -c coll --jsonArray backupfile

其它小知识

  • 客户端连接时,如果报以下warning:
WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
       We suggest setting it to 'never'
WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
       We suggest setting it to 'never'

可以通过以下方式解决:

# 切换到root用户
echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled
echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag

具体原理,可以参考mongo-doc