MongoDB支持在多个机器中通过异步复制达到故障转移和实现冗余。多机器中同一时刻只有一台使用于写操作。
一.主从复制
最常用的复制方式,非常灵活,可用于备份,故障修复,读扩展等
最基本的设置方式就是建立一个主节点和一个或者多个从节点,每个节点要知道主节点的地址,只需要在某一个服务启动时加上-master参数,而另一个服务加上-slave与-source参数,可以实现同步。
首先为主节点建立数据目录,并绑定端口:
然后设置从节点,用到–source来指明主节点的地址:
所有从节点都从主节点复制内容,目前还没有能从从节点复制的机制,原因时从节点没有保存自己的oplog
一个集群中有多少个从节点并没有限制,实际中,从节点个数不要超过12个是最佳的,MongoDB最新版本不再推荐此方案,推荐只用复制集
1.主从复制各个有用的选项含义:
- -only:从节点上指定复制特定某个数据库
- -slavedelay:用在从节点上,当应用主节点的操作增加延时,可以通过
- 时间差,对数据进行恢复
- -fastsync:以主节点的数据库快照为基础启动从节点
- -autoresync:自动重新同步
- -oplogSize:是指主节点oplog的大小(单位:MB)
2.添加和删除
创建从节点时可以不指定主节点,而通过:
>use local
>db.sources.insert({"host" : "192.16.1.50:10000"})
若要更改源:
>db.sources.insert({"host" : "www.zg.com:10000"})
>db.sources.remove({"host" : "192.168.1.50:10000"})
二.复制集
复制集(Replica Set),就是有自动故障恢复功能的主从集群,它和主从集群的最大区别就是复制没有固定的主节点:整个集群会选举出一个主节点,当主节点不能工作时,会选出一个从节点为主节点。复制集总会有一个活跃的节点和一个或者多个备份节点
1.部署复制集
首先,为每个服务器创建数据目录,选择端口:
启动前,给复制集命名以区分复制集,命名为replcopy:
用-replSet让服务器知道这个replcopy复制集还有别的小伙伴,下面启动第二台:
如果还要添加多台,类似指定其他端口就可以
启动后,日志会告诉我们复制集没有初始化,因为还差最后一步:在Shell中初始化复制集
2.初始化复制集
在shell中,连接其中一台服务器,初始化命令只用执行一次:
小伙伴们在使用cmd换行时,切记不要把(){}这样的闭合符号的右边先写上,符号的右括号会导致cmd认为你已经输入完一个命令要开始执行了
代码说明:
- _id:replcopy复制集的名字
- members:复制集中的服务器列表
- _id:每个服务器的唯一ID
- host:指定服务器主机
可用>db.isMaster()
查看哪一台被选为活跃节点
3.复制集中的节点
任何时候,集群中活跃的节点只有一个,其他都是备份的,指定活跃的节点可以随时间而改变,复制集中有以下几种节点:
- standard:常规节点,参与投票,可能成为活跃节点
- passive:存储完整数据的副本,参与投票,不能成为活跃节点
- arbiter:仲裁节点,只参与投票,不接受复制数据,不能成为活跃节点
可修改节点优先级priority完成标准节点和被动节点:
>members.push({"_id":3,"host":"192.168.1.52:10002","priority":50})
//arbiterOnly键可以指定仲裁节点:
>members.push({"_id":2,"host":"192.168.1.52:10002","arbiterOnly":true})
//优先级从0到1000,优先级为0是被动节点不能成为活跃节点,其他节点可按优先级大小更新,备份节点会从活跃节点抽取oplog,并执行操作。活跃节点写操作到自己的本地oplog,这样就成为活跃节点了。
4.故障切换和活跃节点选举
选举新的活跃节点时,若出现僵局,则优先级高的,数据新的成为活跃节点。
三.主从配置信息
在local库中不仅有主从日志oplog集合,还有配置信息(system.replset)
四.管理维护复制集
1.数据库读写分离
用从数据库查询主数据库集合时报错,证明一个从库不能执行查询操作,让从库可以读,分担主库的压力:
>db.getMongo().setSlaveOk()
//先连接从服务器,再输上述代码即可
2.故障转移
如果一个成员出现问题,那么剩余成员会自动选一个作为主库
3.增加节点
MongoDB复制集不仅提供了高可用性的解决方案,还提供了负载均衡的解决方案,增减复制集节点在实际应用中非常普遍。
(1)增加节点
①通过oplog增加节点
配置启动新节点,启用10003这个端口给新的节点:
>mkdir node4文件存放位置
>mkdir node4.log文件存放位置
>mongod --dbpath=D:\mongod\db\node4 --port 10003 --logpath=D:\mongod\logs\node4.log --replSet replcopy/192.168.1.50:10000,192.168.1.51:10001.......
//将新节点添加到复制集:
PRIMARY> rs.add("192.168.1.53:10003")
//用rs.status()可以查看节点同步的状态
②通过数据库快照–fastsync和oplog增加
采用oplog方式会导致数据的不一致。而此种方法解决了这个问题,先去某一个复制集成员的物理文件来作为初始化数据,剩余的部分用oplog日志来追:
>scp node5文件地址
>mkdir node5.log文件地址
//通过scp命令将物理文件取到node5目录下
//配置新节点,采用10004端口给新的节点,将--dbpath指向node5
//代码不再赘述,最后还有添加操作等
(2)减少节点
PRIMARY>rs.remove("192.168.1.53:10003")
注意:
开发者可以通过
>db.runCommand({"getLastError":1,"w":N})
操作确保数据的同步性,此命令会进入阻塞,直到N个服务器复制了最新写入的操作为止
五.管理
1.诊断
当连接到主节点后,使用db.printReplicationInfo()函数,可以查看oplog大小和操作时间范围,当连接到从节点时,这个函数返回从节点信息
2.变更oplog大小
如果oplog大小不合适,最简单的放大就是停掉主节点服务,删除local数据库中的文件,用–oplogSize设置oplog的大小重新启动。
启动主节点后,所有节点都必须用–autoresync重新启动,否则需要手动启动
3.复制认证问题
用设定的密码替换从节点的password,就能通过主节点的认证复制,从节点会用主节点的repl用户,没有则连接第一个用户
>db.addUser("repl", password)