复制集是额外的数据副本,是跨多个服务器同步数据的过程,复制集提供了冗余并增长了数据可用性,经过复制集能够对硬件故障和中断的服务进行恢复。
复制集的优点以下:数据库
- 让数据更安全
- 高数据可用性(24*7)
- 灾难恢复
- 无停机维护(如备份、索引重建、故障转移)
- 读缩放(额外的副本读取)
- 副本集对应用程序是透明的
MongoDB的复制集至少须要两个节点。其中一个是主节点(Primary),负责处理客户端的请求,其他的都是从节点(Secondary),负责复制主节点上的数据。
MongoDB各个节点常见的搭配方式为:一主一从或一主多从。主节点记录其上的全部操做到oplog中,从节点按期轮询主节点获取这些操做,从而保证从节点的数据与主节点一致。
客户端在主节点写入数据,在从节点读取数据,主节点与从节点进行数据交互保障数据的一致性。若是其中一个节点出现故障,其余节点立刻会将业务接过来而无须停机操做。
复制集特色以下:安全
- N个节点的群集
- 任何节点可做为主节点
- 全部写入操做都在主节点上
- 自动故障转移
- 自动恢复
如何建立多实例,在我以前的博客中已经写过,能够参考Yum安装MongoDB及数据库管理每一个实例建立时都应该先建立数据文件目录(mongo)和日志文件(mongod.log),同时在修改配置文件时要注意修改使用不一样的端口号在作复制集时,咱们要多修改一个参数,replication的参数值,并保证多个实例的该参数值都保持一致根据项目要求,需建立额外三个实例,加上原有的一个实例,一共四个实例。
我在作实验的时候发现,MongoDB中对配置文件的格式也有严格要求,在对replication参数值进行修改时要特别注意服务器
replication: replSetName: chenrs //该行内容需在行首空出两个空格,不空格或者多空格都会致使服务启动失败
项目示意图以下:ide
咱们先配置包含三个节点的复制集,多出来的一个节点,会在接下来再作一个节点添加的操做3d
mongo chen={"_id":"chenrs","members":[{"_id":0,"host":"172.16.10.27:27017"},{"_id":1,"host":"172.16.10.27:27018"},{"_id":2,"host":"172.16.10.27:27019"}]}
在初始化复制集时,要确保从节点没有数据,否则在初始化之后会形成从节点服务器的数据丢失。日志
rs.initiate(chen)
chenrs:SECONDARY> rs.status() { "set" : "chenrs", "date" : ISODate("2018-07-14T14:40:20.756Z"), ··· //省略部份内容 "members" : [ { "_id" : 0, "name" : "172.16.10.27:27017", "health" : 1, //健康值为1,表明该节点处于运行良好状态 "state" : 1, //1表明主 "stateStr" : "PRIMARY", //处于peimary状态 ··· //省略部份内容 }, { "_id" : 1, "name" : "172.16.10.27:27018", "health" : 1, "state" : 2, //2表明从 "stateStr" : "SECONDARY", //处于secondary状态 ··· //省略部份内容 }, { "_id" : 2, "name" : "172.16.10.27:27019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", ··· //省略部份内容 } } chenrs:PRIMARY> //此时节点状态已经发生转变
rs.add("172.16.10.27:27020")
rs.remove("172.16.10.27:27020")
ps aux | grep mongod //查询本地的节点的进程号 kill -9 40882 //杀死主节点进程
chenrs:SECONDARY> rs.status() { "set" : "chenrs", "date" : ISODate("2018-07-14T15:21:21.426Z"), "myState" : 2, "term" : NumberLong(2), "syncingTo" : "172.16.10.27:27019", "syncSourceHost" : "172.16.10.27:27019", "syncSourceId" : 2, ··· //省略部份内容 "members" : [ { "_id" : 0, "name" : "172.16.10.27:27017", "health" : 0, //健康值为0,处于停机状态 "state" : 8, "stateStr" : "(not reachable/healthy)", ··· //省略部份内容 }, { "_id" : 1, "name" : "172.16.10.27:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", ··· //省略部份内容 }, { "_id" : 2, "name" : "172.16.10.27:27019", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", ··· //省略部份内容 } }
rs.freeze(30) //暂停30s不参与选举 rs.stepDown(60,30) //交出主节点位置,维持从节点状态很多于60秒,等待30秒使主节点和从节点日志同步