简介
Mongodb 副本集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点或者Arbiter节点。
副本集的所有写操作都交给Primary,Secondary从Primary同步oplog到本实例,以保持复制集内所有成员存储相同的数据集,实现数据的高可用。
常见场景
- 数据冗余
集群可增加延迟写的节点,防止误操作 - 读写分离
适合读多写少的业务
典型结构
集群中的所有节点都可接受读操作;默认的驱动连接时读主节点,可设置read_prefrence指定
A replica set can have up to 50 members but only 7 voting members.
一个集群可以又最多50个节点,但有7个可投票的节点
节点角色
- 主节点(primary)
可接收所有的读写请求;同步oplog到从节点。一个Replica Set只能有一个Primary节点,当Primary挂掉后,其他Secondary或者Arbiter节点会重新选举出来一个主节点。
- 副本节点(secondary)
与主节点保持同样的数据集。当主节点挂掉的时候,参与选主。
- 仲裁者(arbiter)
不保持数据,不可能成为主节点,只进行投票选举主节点。为了打破投票中的偶数个节点的情况,Arbiter几乎没什么大的硬件资源需求.
Do not run an arbiter on systems that also host the primary or the secondary members of the replica set.
不要把仲裁节点与主节点或者从节点放在一台机器
两种结构
- PSS
Primary + Secondary + Secondary模式,通过Primary和Secondary搭建的Replica Set
- PSA
Primary + Secondary + Arbiter模式,使用Arbiter搭建Replica Set
偶数个数据节点,加一个Arbiter构成的Replica Set
选举机制
副本集通过 replSetInitiate 命令或 rs.initiate() 命令进行初始化。
初始化后各个节点开始发送心跳消息,并发起 Primary 选举操作,获得大多数成员投票支持的节点,会成为 Primary,其余节点成为 Secondary。
1 | config = { |
假设复制集内投票成员(后续介绍)数量为 N,则大多数为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出 Primary,复制集将无法提供写服务,处于只读状态
Mongodb副本集的选举基于Bully算法,这是一种协调者竞选算法
Primary 的选举受节点间心跳、优先级、最新的 oplog 时间等多种因素影响
特殊角色
- Arbiter
Arbiter 节点只参与投票,不能被选为 Primary,并且不从 Primary 同步数据。
- Priority==0
Priority0节点的选举优先级为0,不会被选举为 Primary。
- Vote==0
Mongodb 3.0里,复制集成员最多50个,参与 Primary 选举投票的成员最多7个,其他成员(Vote0)的 vote 属性必须设置为0,即不参与投票。
- Hidden==true
Hidden 署行的 节点不能被选为primary(Priority 为0),并且对client 不可见。
- Delayed==time seconds
Delayed 节点必须是 Hidden 节点,否则会出现数据不一致的情况; 其数据落后与 Primary 一段时间(可配置,比如半小时1小时等)
所有角色
Number | Name | State Description |
---|---|---|
0 | STARTUP | 还不是集群中的活跃点,读取配置阶段 |
1 | PRIMARY | 唯一的写节点 |
2 | SECONDARY | 从节点,主节点数据的拷贝 |
3 | RECOVERING | Members either perform startup self-checks, or transition from completing a rollback or resync. |
5 | STARTUP2 | 已经加入集群,同步数据 |
6 | UNKNOWN | |
7 | ARBITER | 仲裁,投票选举primary |
8 | DOWN | 不可达节点 |
9 | ROLLBACK | |
10 | REMOVED | c曾经再集群,但被移除 |
触发选举条件
- 新增一个节点到副本集
- 初始化一个副本集
- primary放弃角色,如 rs.stepDown()/rs.reconfig()
- 从库不能连接到主库(默认超过10s,可通过heartbeatTimeoutSecs参数控制),由从库发起选举
副本集的自动failover是通过心跳检测实现的,进而实现高可用
读写配置
Read Preference
All read preference modes except primary may return stale data because secondaries replicate operations from the primary with some delay. Ensure that your application can tolerate stale data if you choose to use a non-primary mode.
除了primary节点,其他的都有可能读到脏数据。保证你的app能够容忍脏数据
Read Preference Mode | Description |
---|---|
primary | 优先主节点,默认 Multi-document transactions that contain read operations must use read preference primary. All operations in a given transaction must route to the same member. |
primaryPreferred | 主节点优先,主不可用,读从节点 |
secondary | 从节点读取 |
secondaryPreferred | 从节点优先,没有从节点可用,读主节点 |
nearest | 网络延迟最少的节点,不管主从 |
Write Concern
Write concern describes the level of acknowledgment requested from MongoDB for write operations
写操作的确认
选项如下:
1 | { w: <value>, j: <boolean>, wtimeout: <number> } |
w: 写操作已经传播了几个mongod实例
j: 等待写操作写入磁盘journal
wtimeout: 写操作阻塞时间
value | description |
---|---|
w: 1,默认值(写入主节点) w: 0,不需要确认写操作,可能会抛出异常 w: >1, |
|
majority | 大多数数据可投票节点 |
写入一个标记的节点 |
Hidden, delayed, and priority 0 members with member[n].votes greater than 0 can acknowledge majority write operations.
Read Concern(一致性/隔离性)
level | description |
---|---|
local | |
available | |
marjority | |
linearizable | |
snapshot |
配置
- db version v4.2.0
- 配置文件,复制三份,修改
path/dbPath/pidFilePath
bindIp:如果外网,需要将ip绑定为0.0.0.0
1 | # for documentation of all options, see: |
这里我搞了三个,启动
1 | mongod -f /etc/mongod-27017.conf |
随便进入一个实例:
1 | > rs.status() |
初始化后,该实例成为primary,单机实例,增加其他节点
1 | screensaver:PRIMARY> rs.add('127.0.0.1:27018') |
至此, PSA 模式的集群已经创建成功