副本集的组成
Mongodb的复制功能是使用操作日志oplog实现的,操作日志包含了主节点的每一次写操作。oplog是主节点的local数据库中的一个固定集合。
每个备份节点都维护这自己的oplog,记录着每一次从主节点复制数据的操作。
如果某个备份节点挂掉了,重新启动之后会自动从oplog中最后一个操作开始同步。由于复制操作是先复制数据再写入oplog,所以备份节点可能会在已经同步过的数据上再次执行复制操作。
由于oplog的大小是固定的,只能保存特定数量的操作日志。通常oplog使用空间的增长速度和系统处理写请求的速率近乎相同;但是如果执行db.foo.remove()
,如果foo中存在100条数据,则oplog就会有100条操作日志。如果执行大量的批量操作,oplog很快就被填满。
初始化同步
- 选择一个成员作为同步源,在
local.me
中为自己创建一个标识符,删除所有已经存在的数据库 - 克隆(cloning):将同步源的所有记录全部复制到本地。
- 克隆过程中所有操作都会被记录到oplog,如果有文档在克隆过程中移动了,就可能会被遗漏,导致没有被克隆,对于这样的文档,需要重新克隆。
- 将第一个oplog同步过程中的操作记录下来。
- 创建索引,数据大会比较耗时。
- 如果当前节点的数据仍然落后于同步源,oplog同步过程最后一步就是讲创建索引期间的所有操作同步过来,防止该成员成为备份节点。
- 初始化同步完成,切换为普通同步状态,成为备份节点。
STARTUP | 成员刚启动时处于这个状态。在这个状态下,MongoDB会尝试加载成员的副本集配置,配置加载成功后,就会进入STARTUP2。 |
STARTUP2 | 整个初始化同步过程都处于这个状态,但是如果是在普通成员上,这个状态只会持续几秒钟,这个状态下,Mongodb会创建几个县城,用于处理**复制**和**选举**,然后切换到RECOVERING状态。启动时,成员需要做一些检查以确保自己处于有效状态,以后才可以处理读取请求,在启动过程中,成为备份节点之前,每个成员都要经历RECOVERING状态。在处理非常耗时的操作时,成员也可能进入RECOVERING状态;当一个成员与其他成员脱节时,也会进入RECOVERING状态。 |
RECOVERING | 这个状态表明成员运转正常,但是暂时不能处理读取请求,之后才可以处理读取请求,可能会造成轻微的系统过载。 |
ARBITER | 在正常的操作中,仲裁者应该始终处于该状态。 |
出现错误时的状态 | |
DOWN | 如果一个正常运行的成员不可达,就处于DOWN状态。 |
UNKNOWN | 如果一个成员无法到达其他任何成员,其他成员不知道它处于什么状态,会将其报告为UNKNOWN状态。 |
REMOVED | 成员被移除副本集时,就处于该状态。 |
ROLLBACK | 表明该成员正处于数据回滚。 |
FATAL | 成员发生了不可挽回的错误,也不在尝试恢复正常。 |
选举
当一个成员无法到达主节点时,就会申请成为主节点。
希望被选举为主节点的成员,会向他能到达的所有成员发出通知,如果该成员数据落后于副本集,或者已经有一个运行中的主节点,其他成员不会允许选举。
如果该成员得到副本集中“大多数”赞成票,选举成功,切换为主节点。如果不满足票数,选举失败,保持在备份节点状态。
副本集重新配置也会导致主节点退位
回滚
当重新选举主节点时,某一个备份节点的操作数大于主节点的操作数,此时该节点需要将自己的操作数回滚,与主节点相同。