首先,我们看一下 MongoDB 副本集的各种角色。
-
Primary:主服务器,只有一组,处理客户端的请求,一般是读写
-
Secondary:从服务器,有多组,保存主服务器的数据副本,主服务器出问题时其中一个从服务器可提升为新主服务器,可提供只读服务
-
Hidden:一般只用于备份节点,不处理客户端的读请求
-
Secondary-Only:不能成为 primary 节点,只能作为 secondary 副本节点,防止一些性能不高的节点成为主节点
-
Delayed:slaveDelay 来设置,为不处理客户端请求,一般需要隐藏
-
Non-Voting:没有选举权的 secondary 节点,纯粹的备份数据节点。
-
Arbiter:仲裁节点,不存数据,只参与选举,可用可不用
然后我们思考一下 MongoDB 副本集是通过什么方式去进行同步数据的,这里就不得不提到同步所依赖的核心 Oplog
Oplog 其实就像 MySQL 的 Binlog 一样,记录着主节点上执行的每一个操作,而 Secondary 通过复制 Oplog 并应用的方式来进行数据同步。Oplog 的大小是固定的,默认分配5%的可用空间(64位),Oplog 就是一个大小固定、循环复用的日志文件,当 Secondary 落后 Primary 很多,直到 oplog 被复写,那只能重新全量同步,而拉取全量同步代价特别高,直接影响 Primary 的读写性能。
而 MongoDB 可以通过 getLastError 命令来保证写入的安全,但其毕竟不是事务操作,无法做到数据的强一致。
MongoDB 副本集 Secondary 通常会落后几毫秒,如果有加载问题、配置错误、网络故障等原因,延迟可能会更大。