概述:

MongoDB复制集是将数据同步在多个服务器的过程。复制集提高了数据的可用性,并可以保证数据的安全性。复制集是额外的数据副本,是跨多个服务器同步数据的过程,复制集提供了冗余并增加了数据可用性,通过复制集可以对硬件故障和中断的服务进行恢复。

复制集的优势如下:
1.让数据更安全
2.高数据可用性(24*7)
3.灾难恢复
4.无停机维护(如备份、索引重建、故障转移)
5.读缩放(额外的副本读取)
6.副本集对应用程序是透明。

MongoDB复制集的工作原理:

1.mongodb的复制集至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
2.mongodb各个节点常见的搭配方式为:一主一从、一主多从。
3.主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
MongoDB复制集_第1张图片
复制集的特点:
1.N 个节点的集群
2.任何节点可作为主节点
3.所有写入操作都在主节点上
4.自动故障转移
5.自动恢复

部署MongoDB复制集:

我们在同一台服务器上创建MongoDB的多实例,来做MongoDB主从的实验。
我们这里创建四个实例:mongdb1、mongdb2、mongdb3、mongdb4;接下来开始配置复制集:

1.首先在已经安装好的这一台MongoDB服务器上,创建4个实例:
mkdir -p /data/mongodb/mongodb{1,2,3,4} //创建各实例的数据目录
mkdir -p /data/conf/ //创建实例配置目录
mkdir -p /data/logs/ //创建实例的日志目录
touch /data/logs/mongodb{1,2,3,4}.log //创建各实例的日志文件
chmod 777 /data/logs/*.log //赋予日志文件权限777
MongoDB复制集_第2张图片


2.编辑mongodb1.conf配置文件,开启复制集功能并配置replSetName参数
vim /data/mongodb/mongodb1.conf
修改如下:
#mongod.conf
#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb1.log //mongodb1的日志文件路径
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb1/ //mongodb1的数据文件路径
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27017 //mongodb1的进程号
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //删除“#”,开启复制集功能
replSetName: test-rc //名称为test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:
MongoDB复制集_第3张图片


3.复制默认mongodb1.conf配置文件,生成另外三份实例的配置文件
cp -p /data/mongodb/mongodb1.conf /data/conf/mongodb2.conf
cp -p /data/mongodb/mongodb1.conf /data/conf/mongodb3.conf
cp -p /data/mongodb/mongodb1.conf /data/conf/mongodb4.conf
MongoDB复制集


4.分别修改mongodb2.conf、mongodb3.conf、mongodb4.conf配置文件,如下所示:
vim /data/conf/mongodb2.conf修改如下:
#mongod.conf
#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb2.log //mongodb2的日志文件路径
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb2/ //mongodb2的数据文件路径
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27018 //mongodb2的进程号
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //删除“#”,开启复制集功能
replSetName: test-rc #名称为test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:
MongoDB复制集_第4张图片
vim /data/conf/mongodb3.conf修改如下:
#mongod.conf
#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb3.log //mongodb3的日志文件路径
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb3/ //mongodb3的数据文件路径
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27019 //mongodb3的进程号
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //删除“#”,开启复制集功能
replSetName: test-rc #名称为test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:
MongoDB复制集_第5张图片
vim /data/conf/mongodb4.conf修改如下:
#mongod.conf
#for documentation of all options, see:
#http://docs.mongodb.org/manual/reference/configuration-options/
#where to write logging data.
systemLog:
destination: file
logAppend: true
path: /data/logs/mongodb4.log //mongodb4的日志文件路径
#Where and how to store data.
storage:
dbPath: /data/mongodb/mongodb4/ //mongodb4的数据文件路径
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:
#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /data/mongodb/mongodb1/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
#network interfaces
net:
port: 27020 //mongodb4的进程号
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.
#security:
#operationProfiling:
replication: //删除“#”,开启复制集功能
replSetName: test-rc //名称为test-rc
#sharding:
##Enterprise-Only Options
#auditLog:
#snmp:
MongoDB复制集_第6张图片


5.依次启动mongodb四个实例:
mongod -f /data/conf/mongodb1.conf
mongod -f /data/conf/mongodb2.conf
mongod -f /data/conf/mongodb3.conf
mongod -f /data/conf/mongod4.conf
MongoDB复制集_第7张图片
netstat -tunlp | grep mongod //查看端口监听:
MongoDB复制集_第8张图片


6.接下来配置三个节点的复制集:
mongo //登录默认数据库
rs.status() //查看默认端口号27017的复制集状态
MongoDB复制集_第9张图片


7.定义cfg初始化参数(先加入三台,另一台后面实现添加节点功能)
cfg={"_id":"test-rc","members":[{"_id":0,"host":"192.168.48.149:27017"},{"_id":1,"host":"192.168.48.149:27018"},{"_id":2,"host":"192.168.48.149:27019"}]}
MongoDB复制集_第10张图片


8. 启动复制集功能
rs.initiate(cfg)
MongoDB复制集_第11张图片
#注:初始化配置时保证从节点没有数据


9.查看复制集的状态信息
test-rc:PRIMARY> rs.status() //查看已知主节点在192.168.100.100:27017节点上
{
"set" : "test-rc",
"date" : ISODate("2018-09-14T01:59:21.162Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1536890321, 1),
"members" : [
{
"_id" : 0,
"name" : "192.168.48.149:27017",
"health" : 1, //健康值为1 是健康状态
"state" : 1, //1:为主节点 ; 2:为从节点
"stateStr" : "PRIMARY", //"PRIMARY"主节点
"uptime" : 2263,
"optime" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-09-14T01:59:11Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1536890079, 1),
"electionDate" : ISODate("2018-09-14T01:54:39Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.48.149:27018",
"health" : 1,
"state" : 2
"stateStr" : "SECONDARY", //SECONDARY从节点
"uptime" : 291,
"optime" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-09-14T01:59:11Z"),
"optimeDurableDate" : ISODate("2018-09-14T01:59:11Z"),
"lastHeartbeat" : ISODate("2018-09-14T01:59:20.380Z"),
"lastHeartbeatRecv" : ISODate("2018-09-14T01:59:20.895Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.48.149:27017",
"syncSourceHost" : "192.168.48.149:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.48.149:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 291,
"optime" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1536890351, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-09-14T01:59:11Z"),
"optimeDurableDate" : ISODate("2018-09-14T01:59:11Z"),
"lastHeartbeat" : ISODate("2018-09-14T01:59:20.380Z"),
"lastHeartbeatRecv" : ISODate("2018-09-14T01:59:20.923Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.48.149:27017",
"syncSourceHost" : "192.168.48.149:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1536890351, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1536890351, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
MongoDB复制集_第12张图片
MongoDB复制集_第13张图片
MongoDB复制集_第14张图片


10.添加节点并查看复制集的状态信息
rs.add("192.168.48.149:27020")
MongoDB复制集_第15张图片
rs.status()
MongoDB复制集_第16张图片


11.删除端口号为27018的从节点,然后查看复制集
rs.remove("192.168.48.149:27018")
MongoDB复制集_第17张图片
rs.status()
MongoDB复制集_第18张图片


12.故障转移切换

  1. 先退出mogodb,查看一下四个实例的进程信息:
    MongoDB复制集_第19张图片
    2.关闭主节点端口号为27017的进程,检查是否能够自动切换:
    MongoDB复制集_第20张图片
    3.登录MongoDB端口号为27019的实例,然后查看复制集的状态:
    [root@localhost mongodb]# mongo --port 27019 //登录MongoDB端口号为27019的实例
    test-rc:SECONDARY> rs.status() //查看复制集的状态
    查看结果如下:原来的主节点27017进程已被杀掉。端口号27020已经抢占主节点。
    {
    "_id" : 2,
    "name" : "192.168.48.149:27019",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 5203,
    "optime" : {
    "ts" : Timestamp(1536893313, 1),
    "t" : NumberLong(2)
    },
    "optimeDate" : ISODate("2018-09-14T02:48:33Z"),
    "syncingTo" : "192.168.48.149:27020",
    "syncSourceHost" : "192.168.48.149:27020",
    "syncSourceId" : 3,
    "infoMessage" : "",
    "configVersion" : 3,
    "self" : true,
    "lastHeartbeatMessage" : ""
    },
    {
    "_id" : 3,
    "name" : "192.168.48.149:27020",
    "health" : 1,
    "state" : 1,
    "stateStr" : "PRIMARY",
    "uptime" : 1569,
    "optime" : {
    "ts" : Timestamp(1536893313, 1),
    "t" : NumberLong(2)
    },
    "optimeDurable" : {
    "ts" : Timestamp(1536893313, 1),
    "t" : NumberLong(2)
    },
    "optimeDate" : ISODate("2018-09-14T02:48:33Z"),
    "optimeDurableDate" : ISODate("2018-09-14T02:48:33Z"),
    "lastHeartbeat" : ISODate("2018-09-14T02:48:36.644Z"),
    "lastHeartbeatRecv" : ISODate("2018-09-14T02:48:36.935Z"),
    "pingMs" : NumberLong(0),
    "lastHeartbeatMessage" : "",
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "infoMessage" : "",
    "electionTime" : Timestamp(1536892762, 1),
    "electionDate" : ISODate("2018-09-14T02:39:22Z"),
    "configVersion" : 3
    }
    MongoDB复制集_第21张图片
    MongoDB复制集_第22张图片

13.接下来手动切换主节点

  1. rs.freeze(30) //设置暂停30秒不参与选举
    MongoDB复制集_第23张图片
    2.rs.stepDown(60,30)//让出主节点位置,维持从节点状态不少于60秒,等待30秒使主节点和从节点日志同步
    MongoDB复制集_第24张图片
    3.查看复制集的状态信息
    test-rc:SECONDARY> rs.status()//此刻主节点已经在192.168.48.149:27019节点上
    {
    "set" : "test-rc",
    "date" : ISODate("2018-09-14T03:01:48.447Z"),
    "myState" : 2,
    "term" : NumberLong(3),
    "syncingTo" : "192.168.48.149:27019",
    "syncSourceHost" : "192.168.48.149:27019",
    "syncSourceId" : 2,
    "heartbeatIntervalMillis" : NumberLong(2000),
    "optimes" : {
    "lastCommittedOpTime" : {
    "ts" : Timestamp(1536894107, 1),
    "t" : NumberLong(3)
    },
    "readConcernMajorityOpTime" : {
    "ts" : Timestamp(1536894107, 1),
    "t" : NumberLong(3)
    },
    "appliedOpTime" : {
    "ts" : Timestamp(1536894107, 1),
    "t" : NumberLong(3)
    },
    "durableOpTime" : {
    "ts" : Timestamp(1536894107, 1),
    "t" : NumberLong(3)
    }
    },
    "lastStableCheckpointTimestamp" : Timestamp(1536894097, 1),
    "members" : [
    {
    "_id" : 0,
    "name" : "192.168.48.149:27017",
    "health" : 0,
    "state" : 8,
    "stateStr" : "(not reachable/healthy)",
    "uptime" : 0,
    "optime" : {
    "ts" : Timestamp(0, 0),
    "t" : NumberLong(-1)
    },
    "optimeDurable" : {
    "ts" : Timestamp(0, 0),
    "t" : NumberLong(-1)
    },
    "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
    "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
    "lastHeartbeat" : ISODate("2018-09-14T03:01:47.657Z"),
    "lastHeartbeatRecv" : ISODate("2018-09-14T02:39:11.212Z"),
    "pingMs" : NumberLong(0),
    "lastHeartbeatMessage" : "Error connecting to 192.168.48.149:27017 :: caused by :: Connection refused",
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "infoMessage" : "",
    "configVersion" : -1
    },
    {
    "_id" : 2,
    "name" : "192.168.48.149:27019",
    "health" : 1,
    "state" : 1,
    "stateStr" : "PRIMARY",
    "uptime" : 2359,
    "optime" : {
    "ts" : Timestamp(1536894097, 1),
    "t" : NumberLong(3)
    },
    "optimeDurable" : {
    "ts" : Timestamp(1536894097, 1),
    "t" : NumberLong(3)
    },
    "optimeDate" : ISODate("2018-09-14T03:01:37Z"),
    "optimeDurableDate" : ISODate("2018-09-14T03:01:37Z"),
    "lastHeartbeat" : ISODate("2018-09-14T03:01:47.181Z"),
    "lastHeartbeatRecv" : ISODate("2018-09-14T03:01:48.314Z"),
    "pingMs" : NumberLong(0),
    "lastHeartbeatMessage" : "",
    "syncingTo" : "",
    "syncSourceHost" : "",
    "syncSourceId" : -1,
    "infoMessage" : "",
    "electionTime" : Timestamp(1536894006, 1),
    "electionDate" : ISODate("2018-09-14T03:00:06Z"),
    "configVersion" : 3
    },
    {
    "_id" : 3,
    "name" : "192.168.48.149:27020",
    "health" : 1,
    "state" : 2,
    "stateStr" : "SECONDARY",
    "uptime" : 5985,
    "optime" : {
    "ts" : Timestamp(1536894107, 1),
    "t" : NumberLong(3)
    },
    "optimeDate" : ISODate("2018-09-14T03:01:47Z"),
    "syncingTo" : "192.168.48.149:27019",
    "syncSourceHost" : "192.168.48.149:27019",
    "syncSourceId" : 2,
    "infoMessage" : "",
    "configVersion" : 3,
    "self" : true,
    "lastHeartbeatMessage" : ""
    }
    ],
    "ok" : 1,
    "operationTime" : Timestamp(1536894107, 1),
    "$clusterTime" : {
    "clusterTime" : Timestamp(1536894107, 1),
    "signature" : {
    "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    "keyId" : NumberLong(0)
    }
    }
    }
    MongoDB复制集_第25张图片

本章总结:

1.mongodb复制集(Replica Sets)是额外的数据副本,复制集提供了冗余和增加数据可用性。
2.mongodb的复制集至少需要两个节点。其中主节点负责处理客户端请求,从节点负责复制主节点上的数据。
3.mongodb复制集可以实现群集的高可用,当主节点出现故障时会自动切换到其他节点。管理员也可以手动进行复制集的主从切换。
4.复制是基于操作日志oplog,相当于MySQL中的二进制日志,只记录发生改变的记录。复制是将主节点的oplog日志同步并应用到其他从节点的过程。
5.节点类型分为标准节点、被动节点和仲裁节点。只有标准节点可能被选举为活跃(主)节点。
6.尽量保证主节点的oplog足够大,能够存放相当长时间的操作记录。