简介
复制集(Replica Sets)是额外的数据副本,是跨多个服务器同步数据的过程,复制集提供了冗余并增加了数据可用性,通过复制集可以对硬件故障和中断的服务进行恢复
复制集的优势
- 让数据更安全
- 高数据可用性(24*7)
- 灾难恢复
- 无停机维护(如备份、索引重建、故障转移)
- 读缩放(额外的副本读取)
- 副本集对应程序是透明的
复制集的特点
- N个节点的群集
- 任何节点可作为主节点
- 所有写入操作都在主节点上
- 自动故障转移
- 自动恢复
复制集工作原理
1.MongoDB的复制集至少需要两个节点。其中一个是主节点(Primary),负责处理客户端的请求,其余的都是从节点(Secondary),负责复制主节点上的数据。
2.MongoDB各个节点常见的搭配方式为:一主一从或一主多从。主节点记录其上的所有操作到oplog中,从节点定期轮询主节点获取的这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致
3.如上图可以看出,客户端在主节点写入数据,才从节点读取数据,主节点与从节点进行数据交互保障数据的一致性。如果其中一个节点出现故障,其他节点马上会将业务接过来而无需停机操作
一、安装MongoDB
1、自定义yum源文件
[[email protected]_6 ~]# cd /etc/yum.repos.d/
[[email protected]_6 yum.repos.d]# mkdir bak
[[email protected]_6 yum.repos.d]# mv CentOS-* bak/
[[email protected]_6 yum.repos.d]# vim local.repo
[mongodb-org]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
2、安装MongoDB
[[email protected]_6 ~]# yum -y install mongodb-org
[[email protected]_6 ~]# yum clean all #清除yum缓存
[[email protected]_6 ~]# yum list #重新加载源
二、配置复制集
1、创建实例相关文件
[[email protected]_6 ~]# mkdir -p /data/mongodb/mongodb{1,2,3,4} #创建数据目录
[[email protected]_6 ~]# mkdir -p /data/logs/mongodb #创建日志目录
[[email protected]_6 ~]# cd /data/logs/mongodb/
[[email protected]_6 mongodb]# touch mongodb{1,2,3,4}.log #创建日志文件
[[email protected]_6 mongodb]# chmod 777 *.log #修改目录权限
2、编辑实例1配置文件
[[email protected]_6 ~]# cp -p /etc/mongod.conf /etc/mongod1.conf
[[email protected]_6 ~]# vim /etc/mongod1.conf #修改配置文件
path: /data/logs/mongodb/mongodb1.log #约第10行,编辑日志文件路径,对应其他的实例依次往下……
dbPath: /data/mongodb/mongodb1/ #编辑数据目录文件路径,也是一样对应其他的实例依次往下……
net: #约28行,指定网络接口
port: 27017 #编辑端口号,实例1为27017,实例2为27018,依次往下排……
bindIp: 0.0.0.0
replication: #约37行,打开复制选项注释,四台实例都要添加
replSetName: kgcrs #指定复制集名称
3、编辑其他实例配置文件
[[email protected]_6 ~]# cp -p /etc/mongod1.conf /etc/mongod2.conf #创建其他三个MongoDB实例配置文件
[[email protected]_6 ~]# cp -p /etc/mongod1.conf /etc/mongod3.conf
[[email protected]_6 ~]# cp -p /etc/mongod1.conf /etc/mongod4.conf
[[email protected]_6 ~]# rm -rf /etc/mongod.conf
4、编写启动脚本
[[email protected]_6 ~]# vim /etc/init.d/mongodb
#!/bin/bash
# descript:Mongodb Server Control Script
# Author: GuiHaiYiDao TEL:139741741741
# date:long long ago
instance=$1
action=$2
case "$action" in
‘start‘)
/usr/bin/mongod -f /etc/"$instance".conf
;;
‘stop‘)
/usr/bin/mongod -f /etc/"$instance".conf --shutdown
;;
‘restart‘)
/usr/bin/mongod -f /etc/"$instance".conf --shutdown
/usr/bin/mongod -f /etc/"$instance".conf
;;
esac
[[email protected]_6 ~]# chmod +x /etc/init.d/mongodb
[[email protected]_6 ~]# /etc/init.d/mongodb mongod1 start
[[email protected]_6 ~]# /etc/init.d/mongodb mongod2 start
[[email protected]_6 ~]# /etc/init.d/mongodb mongod3 start
[[email protected]_6 ~]# /etc/init.d/mongodb mongod4 start
[[email protected]_6 ~]# netstat -anpt | grep ‘mongod‘
5、初始化配置复制集
[[email protected]_6 ~]# mongo --port 27017 #进入第一个实例
> rs.status() #查看复制集的状态信息
{
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "no replset config has been received", #此参数指定没有接收到复制集配置
"code" : 94,
"codeName" : "NotYetInitialized"
}
> cfg={"_id":"kgcrs","members":[{"_id":0,"host":"192.168.100.76:27017"},{"_id":1,"host":"192.168.100.76:27018"},{"_id":2,"host":"192.168.100.76:27019"}]} #cfg定义变量作为初始化参数;kgcrs定义复制集名称;members定义节点成员
{
"_id" : "kgcrs",
"members" : [
{
"_id" : 0,
"host" : "192.168.100.71:27017"
},
{
"_id" : 1,
"host" : "192.168.100.72:27018"
},
{
"_id" : 2,
"host" : "192.168.100.73:27019"
}
]
}
> rs.initiate(cfg) #初始化复制集
{
"ok" : 1,
"operationTime" : Timestamp(1536499691, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1536499691, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
kgcrs:SECONDARY> rs.status() #再次查看复制集状态信息
{
"set" : "kgcrs", #复制集群集名称
"date" : ISODate("2018-09-09T13:29:34.203Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.100.76:27017", #复制集成ip以及端口号
"health" : 1, #健康状况,1代表健康;0代表宕机
"state" : 1, #1代表主节点;2代表从节点
"stateStr" : "PRIMARY", #PRIMARY代表主节点;SECONDARY代表从节点
"uptime" : 172,
"optime" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-09-09T13:29:24Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1536499703, 1),
"electionDate" : ISODate("2018-09-09T13:28:23Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.100.76:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 82,
"optime" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-09-09T13:29:24Z"),
"optimeDurableDate" : ISODate("2018-09-09T13:29:24Z"),
"lastHeartbeat" : ISODate("2018-09-09T13:29:33.324Z"),
"lastHeartbeatRecv" : ISODate("2018-09-09T13:29:32.404Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.100.76:27017",
"syncSourceHost" : "192.168.100.76:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.100.76:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 82,
"optime" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1536499764, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2018-09-09T13:29:24Z"),
"optimeDurableDate" : ISODate("2018-09-09T13:29:24Z"),
"lastHeartbeat" : ISODate("2018-09-09T13:29:33.324Z"),
"lastHeartbeatRecv" : ISODate("2018-09-09T13:29:32.383Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.100.76:27017",
"syncSourceHost" : "192.168.100.76:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1536499764, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1536499764, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
6、增加节点
kgcrs:PRIMARY> rs.add("192.168.100.76:27020") #增加节点
{
"ok" : 1,
"operationTime" : Timestamp(1536500454, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1536500454, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
kgcrs:PRIMARY> rs.status() #再次查看复制集状态信息
7、删除节点
kgcrs:PRIMARY> rs.remove("192.168.100.76:27020") #删除节点
kgcrs:PRIMARY> rs.status() #再次查看
kgcrs:PRIMARY> exit
三、复制集切换
1、模拟故障自动转移
[[email protected]_6 ~]# ps aux | grep mongod | grep -v grep
[[email protected]_6 ~]# kill -9 10706
[[email protected]_6 ~]# mongo --port 27018
kgcrs:PRIMARY> rs.status() #查看复制状态
2、手动进行主从切换
kgcrs:PRIMARY> exit
[[email protected]_6 ~]# /etc/init.d/mongodb mongod1 start #再次启动实例1
[[email protected]_6 ~]# mongo --port 27018 #此时主节点是在第二台实例中
kgcrs:PRIMARY> rs.status()
kgcrs:PRIMARY> rs.freeze(30) #暂停30秒不参加选举
kgcrs:PRIMARY> rs.stepDown(60,30) #告知主节点交出主节点位置,然后维持从节点状态不少于60秒,同时等待30秒以使主节点和从节点日志同步
kgcrs:SECONDARY> rs.status()
四、测试复制集同步
1、主节点添加测试数据
[[email protected]_6 ~]# mongo --port 27017
kgcrs:PRIMARY> use supermarket
kgcrs:PRIMARY> for(var i=0;i<=100;i++)db.product.insert({"id":1,"pname":"Audi"+i})
2、手动进行主从切换
kgcrs:PRIMARY> rs.freeze(30)
kgcrs:PRIMARY> rs.stepDown(60,30)
kgcrs:SECONDARY> rs.status()
3、登录第二个实例服务器
[[email protected]_6 ~]# mongo --port 27017
kgcrs:PRIMARY> use supermarket
kgcrs:PRIMARY> db.product.find()
原文地址:http://blog.51cto.com/11905606/2174286