Mongodb的副本集集群设置
mongodb副本集介绍
mongodb支持两种类型的集群架构:
- 类似于mysql的master/slave的主从复制集群,不过此集群已经很少使用了,貌似不支持故障自动转移;
- 副本集集群:多个节点共属于同一个副本集,有一个主节点和若干的从节点,主节点读写,从节点只读。支持故障自动转移,是目前常用的架构;
mongodb副本集工作原理
工作原理如下:
- mongodb有一个local库,此库记录了所有的mongodb副本集元数据和oplog信息,此库维护着oplog日志,此日志位于local库中的oplog.rc collection中,此collection只有开启了副本集功能加入副本集之后才会生成。oplog日志是有大小的,不像mysql的二进制日志可以一直写入。此日志大小默认为可用磁盘空间的5%,不满1G按照1G计算,大小可以自己定义;
- 主节点把所有的数据变化写入到oplog中,从节点复制主节点的oplog并保存到自己的oplog进行数据重现以保持主从节点的数据一致;
- 主节点每2秒往各从节点发送一次心跳信息,如果各从节点10秒钟还没有收到主节点的心跳信息则会触发选举;
注意:
- 副本集的节点个数至少需要3个以上,必须有一个仲裁节点,预防发生脑裂行为;
- 只有主节点才会写oplog,从节点只能从主节点复制oplog。但是每个节点都会持有一个oplog,因为所以节点(除了特殊节点)都可能会被选举为主节点;
mongodb选举影响因素
- 心跳信息
- 各节点优先级
- optime:数据副本新鲜度
- 网络连接
触发选举的因素
- 主节点收到stepDown指令
- 出现优先级更高的节点
- 主节点联系不到大多数节点
mongodb副本集的特殊节点
- 0优先级的节点:此节点可以和正常节点一样持有副本集,也可以参与选举,但是不会主动被选举为主节点。所以通常作为冷备节点使用,常用于异地容灾架构;
- 被隐藏的从节点:此节点首先必须是0优先级的节点,而且此节点对客户端不可见,在mongodb的很多状态信息中也看不到它,但是它有用选举权;
- 延迟复制节点:必须是0优先级节点,它也不能成为主节点,但是数据落后于主节点,常用于防止人工误删除数据;
- arbiter:仲裁节点,安装mongodb就行,不持有副本集,没有选举权;
mongodb副本集步骤
- 克隆所有的数据库;
- 复制oplog到本地,应用所有的数据改变操作;
- 为所有collection构建索引
副本集具体操作
- 副本集各节点配置文件需要添加如下配置:
- replSet:副本集名字 相同副本集节点都需要设置为一致的;
- replIndexprefetch:{none|_id_only|all} 实现索引预取,_id_only表示只取_id_字段索引;
- 启动mongodb服务,主节点执行rs.initiate()操作,初始化数据集;
- 主节点执行rs.add(),添加各从节点,此时执行rs.status()可以看到各个节点的信息,执行db.isMaster()可以查看自己是否为主节点;
- 从节点此时还无法进行读取操作,从节点执行rs.slaveOk()操作表示开启从节点读取操作,此时从节点可以正常查询数据;
- 各节点执行rs.printReplicationInfo()可以查看自己的oplog同步时间信息;
- 各节点执行rs.printSlaveReplicationInfo()可以查看各从节点是否落后于主节点;
- 此时主节点故障则其他从节点会自动进行切换操作,也可以执行rs.stepDown()操作手动把主节点下线,此时主节点会自动切换为从节点;
mongodb副本集常用操作命令:
rs.status() 查看副本集状态信息,包括各节点信息;
rs.initiate() 主节点用于进行副本集初始化;
rs.conf() 查看副本集配置信息
rs.reconf() 应用指定的副本集配置信息
rs.add() 添加从节点
rs.addArb() 添加仲裁节点
rs.stepDown() 手动把主节点下线
rs.freeze() 表示指定时间内不允许进行主节点切换
rs.remove() 删除指定从节点
rs.slaveOk() 从节点允许读操作
rs.printReplicationInfo() 查看自己的oplog time信息
rs.printSlaveReplicationInfo() 查看各从节点是否落后于主节点
db.isMaster() 查看自己是否为主节点
修改副本集conf信息:
- conf=rs.conf() 把当前配置信息赋值给一个变量;
- conf.members[1].priority=2 表示修改节点1的优先级为2。以此类推,所有配置都可以这样修改;
- rs.reconf(conf) 重新应用修改好的配置信息
配置副本集遇到的问题:
- 主节点无法加进从节点:
原因是从节点不能执行rs.initiate()操作,否则每个节点都会把自己变成主节点,再次添加会报错,提示节点ID都是相同的; - 从节点无法进行数据读取:
没有执行rs.slaveOK()的原因。注意:主节点可以读写,从节点只读。而且很多操作只能在主节点进行。