一 复制集概念

A 复制集概述

Mongodb复制集(replica set)由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客户端)的所有数据都写入Primary,Secondary通过oplog来同步Primary的数据,保证主从节点数据的一致性;
复制集在完成主从复制的基础上,通过心跳机制,一旦Primary节点出现宕机,则触发选举一个新的主节点,剩下的secondary节点指向新的Primary,时间应该在10-30s内完成感知Primary节点故障,实现高可用数据库集群
特点:

  • Primary节点是唯一的,但不是固定的
  • 由大多数据原则保证数据的一致性
  • Secondary节点无法写入(默认情况下,不使用驱动连接时,也是不能查询的)
  • 相对于传统的主从结构,复制集可以自动容灾

B 复制集原理

角色(按是否存储数据划分):

  • Primary
    主节点,由选举产生,负责客户端的写操作,产生oplog日志文件
  • Secondary
    从节点,负责客户端的读操作,提供数据的备份和故障的切换
  • Arbiter
    仲裁节点,只参与选举的投票,不会成为primary,也不向Primary同步数据

若部署了一个2个节点的复制集,1个Primary,1个Secondary,任意节点宕机,复制集将不能提供服务了(无法选出Primary),这时可以给复制集添加一个Arbiter节点,即使有节点宕机,仍能选出Primary

角色(按类型区分):

  • Standard(标准)
    这种是常规节点,它存储一份完整的数据副本,参与投票选举,有可能成为主节点
  • Passive(被动)
    存储完整的数据副本,参与投票,不能成为活跃节点
  • Arbiter(投票)
    仲裁节点只参与投票,不接收复制的数据,也不能成为活跃节点

每个参与节点(非仲裁者)有个优先权(0-1000),优先权(priority)为0则是被动的,不能成为活跃节点;
优先权不为0的,按照由大到小选出活跃节点,优先值一样的则看谁的数据比较新
Mongodb 3.0里,复制集成员最多50个,参与Primary选举投票的成员最多7个

C 选举

每个节点通过优先级定义出节点的类型(标准、被动、投票)
标准节点通过对比自身数据进行选举出primary节点或者secondary节点
影响选举的因素:

  1. 心跳检测
    复制集内成员每隔两秒向其他成员发送心跳检测信息,若10秒内无响应,则标记其为不可用
  2. 节点数量
    在多个节点中,最少保证两个节点为活跃状态,如果集群中共三个节点,挂掉两个节点,那么剩余的节点无论状态是primary还是处于选举过程中,都会直接被降权为secondary

触发选举的情况:

  1. 初始化状态
  2. 从节点们无法与主节点进行通信
  3. 主节点辞职

主节点辞职的情况:

  • 在接收到replSetStepDown命令后
  • 在现有的环境中,其他secondary节点的数据落后于本身10s内,且拥有更高优先级
  • 当主节点无法与群集中多数节点通信

当主节点辞职后,主节点将关闭自身所有的连接,避免出现客户端在从节点进行写入操作

二 复制集搭建

A 配置文件准备

创建目录

1
mkdir -p /opt/mongodb/2802{0,1,2,3}/{conf,data,log}

创建单个配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[mongo@noah ~]$ vim /opt/mongodb/28020/conf/mongod.conf
systemLog:
destination: file
path: /opt/mongodb/28020/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /opt/mongodb/28020/data
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
port: 28020
replication:
oplogSizeMB: 2048
replSetName: my_repl

复制配置文件为多份

1
2
3
cp /opt/mongodb/2802{0,1}/conf/mongod.conf
cp /opt/mongodb/2802{0,2}/conf/mongod.conf
cp /opt/mongodb/2802{0,3}/conf/mongod.conf

修改配置文件端口

1
2
3
sed -i 's#28020#28021#g' /opt/mongodb/28021/conf/mongod.conf
sed -i 's#28020#28022#g' /opt/mongodb/28022/conf/mongod.conf
sed -i 's#28020#28023#g' /opt/mongodb/28023/conf/mongod.conf

B 配置复制集群

启动多个mongodb

1
2
3
4
mongod -f /opt/mongodb/28020/conf/mongod.conf
mongod -f /opt/mongodb/28021/conf/mongod.conf
mongod -f /opt/mongodb/28022/conf/mongod.conf
mongod -f /opt/mongodb/28023/conf/mongod.conf

创建复制集群

1
2
3
4
5
6
7
mongo --port 28020
config = {_id: 'my_repl', members: [
{_id: 0, host: '192.168.3.241:28020'},
{_id: 1, host: '192.168.3.241:28021'},
{_id: 2, host: '192.168.3.241:28022'}]
}
rs.initiate(config)

查看复制集状态:

1
2
3
rs.status();    //查看整体复制集状态
rs.isMaster(); // 查看当前是否是主节点
rs.conf(); //查看复制集配置情况

C 复制集群修改

添加删除节点

1
2
3
rs.remove("ip:port"); // 删除一个节点
rs.add("ip:port"); // 新增从节点
rs.addArb("ip:port"); // 新增仲裁节点

重新配置集群

1
2
3
4
5
6
config = {_id: 'my_repl', members: [
{_id: 0, host: '192.168.3.241:28020'},
{_id: 1, host: '192.168.3.241:28021'},
{_id: 2, host: '192.168.3.241:28022',"arbiterOnly":true}]
}
rs.reconfig(config)

三 复制集特殊节点

A 特殊节点:

  • arbiter节点
    主要负责选主过程中的投票,但是不存储任何数据,也不提供任何服务
  • hidden节点
    隐藏节点,不参与选主,也不对外提供服务。
  • delay节点
    延时节点,数据落后于主库一段时间,因为数据是延时的,也不应该提供服务或参与选主,所以通常会配合hidden(隐藏)
    一般情况下会将delay+hidden一起配合使用

添加特殊节点的方法

  1. 可以在搭建过程中设置特殊节点
  2. 可以通过修改配置的方式将普通从节点设置为特殊节点
    需要找到需要改为延迟性同步的数组号,然后修改数据数据

B 配置延时节点

查看所有节点的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> rs.conf()
"members" : [
{
"_id" : 0, --->成员号
"host" : "10.0.0.51:28017", --->节点信息
"arbiterOnly" : false, --->是否为仲裁节点
"buildIndexes" : true,
"hidden" : false, --->是否为隐藏节点
"priority" : 1, ---->选主权重
"tags" : {
},
"slaveDelay" : NumberLong(0), --->延时的时间
"votes" : 1
}

在线修改配置:

1
2
3
4
5
6
7
8
9
10
#将所有配置信息定义到一个变量cfg 中      
cfg=rs.conf()

#从[成员号]对应的成员配置信息,调取某项配置进行修改
cfg.members[3].priority=0
cfg.members[3].hidden=true
cfg.members[3].slaveDelay=120

#重新加载配置
rs.reconfig(cfg)

取消以上配置

1
2
3
4
5
cfg=rs.conf() 
cfg.members[3].priority=1
cfg.members[3].hidden=false
cfg.members[3].slaveDelay=0
rs.reconfig(cfg)

注意:如果所有节点,没有0号节点时,members[号码],不再是_id值了,要手工数一下成员的位置号(从0开始数)

配置成功后,通过以下命令查询配置后的属性

1
rs.conf(); 

四 集群读写分离

对于MongoDB来说,主节点一般用于写数据,从节点用于读数据,且主节点也并不是固定的(当主节点宕机后会选举出一个新的主节点),所以在生产环境时客户端不能直连主节点,要配置集群节点

1
2
3
<mongo:mongo-client replica-set="ip1:port1,ip2:port2,ip3:port3">
<mongo:client-options read-preference="SECONDARY_PREFERRED"/>
</mongo:mongo-client>

通过read-preference参数控制读写分离方式,其类型有以下几种:

  • PRIMARY(默认)
    读操作都在主节点,若主节点不可用则报错。
  • PRIMARY_PREFERRED
    首选主节点,若主节点不可用则转移到其它从节点。
  • SECONDARY
    读从节点,不可用则报错。
  • SECONDARY_PREFERRED(推荐)
    首选从节点,若是特殊情况则在主节点读(但主节点架构)。
  • NEAREST
    最邻近主节点。

五 副本集其他操作命令:

  1. 查看副本集的配置信息
1
2
3
admin> rs.config()
或者
admin> rs.conf()
  1. 查看副本集各成员的状态
1
admin> rs.status()
  1. 副本集角色切换(不要人为随便操作)
1
2
3
4
admin> rs.stepDown()
注:
admin> rs.freeze(300) //锁定从,使其不会转变成主库
freeze()和stepDown单位都是秒。
  1. 设置副本节点可读:在副本节点执行
1
admin> rs.slaveOk()
  1. 查看副本节点(监控主从延时)
1
2
3
4
admin> rs.printSlaveReplicationInfo()
source: 192.168.1.22:27017
syncedTo: Thu May 26 2016 10:28:56 GMT+0800 (CST)
0 secs (0 hrs) behind the primary