1·MongoDB 复制集概述
2·MongoDB 复制集部署
3·MongoDB 复制集管理(添加、移除等)
4·复制集的总结mongodb
以前的一片文章讲了 MongoDB 的安装和平常的操做,有兴趣的朋友能够看看 MongoDB 的安装和简单操做vim
1)什么是复制集?安全
复制集是额外的一种数据副本,是跨多个服务器同步数据的过程,通俗的说就是能够在不一样的服务器上备份数据,专业点说就是冗灾处理。经过复制集能够对硬件和终端的服务进行恢复。服务器
2)复制集的优点以下:app
1-让数据更加安全---(确定啊,都是备份了,能不安全吗!) 2-数据的高可用性---(能够整年无休,7*24小时×××) 3-灾难恢复 ----(不用多说,既然是数据,能没有恢复吗) 4-无停机维护---(好比说,备份、索引的重建等,MySQL 备份就须要锁定 表 、或者行,而它不会) 5-读缩放----(额外的副本读取) 6-它对应用程序是透明的
3)复制集工做原理是什么?ide
1·既然是一个功能性的东西,那么存在确定有它的工做原理和过程。MongoDB 的复制集至少须要两个节点,是至少。其中一个是主节点 (Primary),这个主节点主要负责处理客户端的请求,其余的都是从节点 (Secondary),负责复制主节点上的数据。日志
2·那么咱们经常使用的搭配方式有:一主一丛或一主多从,由于复制集的主从的选举原理是从节点不容许选举为当主节点,可是在实际的生产环境中,主服务器是不可能单点挂上去的,这样要是主服务器挂掉了,那就凉凉。code
3·客户端主节点写入数据,在从节点读取数据,主节点与从节点进行数据交互保障数据的统一性。若是其中一个节点出现故障,其余节点立刻会把业务接过来而无需停机操做。blog
4·下图是 MongoDB 复制集结构图索引
它的特色以下:
N个节点的群集
任何节点可做为主节点
全部写入都是在主节点,读取是在从节点,实现读写分离
自动故障转移
自动恢复
先介绍下环境:CenOS 7.4 上部署
部署前提:安装 MongoDB ,了解什么是实列、和建立多个实例
这里安装 MongoDB 就再也不演示。我是直接 YUM 装的。
须要了解 MongoDB 安装 和 多实例的建立 请访问:MongoDB 的安装和命令
须要了解 MongoDB 与 MySQL 的区别 请访问:MySQL - mmm 高可用集群
须要了解 MySQL 的读写分离 请访问:MySQL 主从复制 + 读写分离
1)看多 MongoDB 的多实例建立的知道,建立实例前须要建立数据文件和日志文件存储路径。
[root@localhost ~]# mkdir -p /data/mongodb/mongodb{2,3,4} ----(建立3个数据文件,由于本身 yum 安装了一个,因此也算一个。)
[root@localhost ~]# mkdir -p /data/mongodb/logs ----(建立日志文件路径)
[root@localhost ~]# cd /data/mongodb/logs/
[root@localhost logs]# touch mongodb{2,3,4}.log -----(建立日志文件夹)
[root@localhost logs]# chmod 777 *.log -----(给最大的权限)
2)修改主配置文件 ---- (须要注意的地方用加粗方式显示)
[root@localhost ~]# vim /etc/mongod.conf ----(修改主配置文件)
修改内容以下:
#network interfaces
net:port: 27017 ----(默认端口号)
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces. ------------(修改监听地址)#security:
#operationProfiling:
replication: -----------------(这里须要去掉注释)
replSetName: kgcrs ------------(在这里须要添加复制集的名字)
3)配置多实列 2 ,而且修改数据存储路径和日志文件
[root@localhost ~]# cp -p /etc/mongod.conf /etc/mongod2.conf ----(把主配置文件复制一份)
[root@localhost ~]# vim /etc/mongod2.conf -----(修改实列的配置文件)
修改内容以下: ---(修改内容以加粗方式显示)
systemLog:
destination: file
logAppend: truepath: /data/mongodb/logs/mongod2.log ----(日志文件的位子,这里须要注意路径,不能写错,以前建立的位置也不能有错)
#Where and how to store data.
storage:dbPath: /data/mongodb/mongodb2 ----(数据存储路径,以前建立的路径必须同样)
journal:
enabled: true
#engine:
#mmapv1:
#wiredTiger:#how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo#network interfaces
net:port: 27018 -----(端口号须要修改成不同的,本身能记住就行。)
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.#security:
#operationProfiling:
replication:
replSetName: kgcrs ——(复制集的名称都须要一致,名字能够本身修改)
4)配置多实例 三、4 (和上一步都是同样,只是数据路径,和日志文件,还有端口号须要修改)
[root@localhost mongodb]# cp -p /etc/mongod2.conf /etc/mongod3.conf
[root@localhost mongodb]# cp -p /etc/mongod2.conf /etc/mongod4.conf
这里就再也不分别演示修改方式,会以一张图来讲明:修改数据路径、日志文件、端口号
下图是多实例修改样本:
5)当配置文件都 OK 后,就能够把4个实例所有启动:
[root@localhost ~]# mongod -f /etc/mongod.conf ---(第一台实例,是本身用YUM 装的,能够看做一台实例。)
[root@localhost ~]# mongod -f /etc/mongod2.conf ----(第二台实例,须要注意,若是有报错,很大一部分缘由都是配置文件有问题,仔细检查配置文件的路径等问题)
[root@localhost ~]# mongod -f /etc/mongod3.conf ----(第三台实例)
[root@localhost ~]# mongod -f /etc/mongod4.conf ----(第4台实例)
6)进入第一台实例,初始化复制集配置 ---(以上步骤只是建立实例,并非复制集哦。)
[root@localhost ~]# mongo ---(由于第一台的端口默认是 27017,因此这里不用跟端口号,若是是其余实例就须要 加上 --port 27018)
cfg={"_id":"kgcrs","members":[{"_id":0,"host":"192.168.198.128:27017"},{"_id":1,"host":"192.168.198.128:27018"},{"_id":2,"host":"192.168.198.128:27019"}]}
这里须要说明此代码:这里包含了3个节点的复制集,格式不须要变,由于这里是实验环境,因此 IP 是相同的,在生产环境中,IP 地址是不同的。这里只须要修改端口号就行,还有就是咱们一共是4个实例,可是这里只有3个,还剩下一个是为以后演示添加节点。
rs.initiate(cfg) ----(从新加载一下复制集,以后会有以下图的解释)
kgcrs:PRIMARY> rs.status() -----(查看复制集状态)
"set" : "kgcrs", ----(复制集名称) "date" : ISODate("2018-09-16T04:29:54.105Z"), "myState" : 1, "term" : NumberLong(1), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "192.168.198.128:27017", -----(节点详细信息) "health" : 1, -----(健康值为 “1” 说明是在线状态。“0” 为宕机状态) "state" : 1, "stateStr" : "PRIMARY", ------(主节点 PRIMARY) "uptime" : 848, "optime" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-09-16T04:29:48Z"), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1537072157, 1), "electionDate" : ISODate("2018-09-16T04:29:17Z"), "configVersion" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 1, "name" : "192.168.198.128:27018",------(第二台节点) "health" : 1, "state" : 2, "stateStr" : "SECONDARY", -----(**从节点SECONDARY )** "uptime" : 47, "optime" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-09-16T04:29:48Z"), "optimeDurableDate" : ISODate("2018-09-16T04:29:48Z"), "lastHeartbeat" : ISODate("2018-09-16T04:29:53.346Z"), "lastHeartbeatRecv" : ISODate("2018-09-16T04:29:53.725Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "192.168.198.128:27017", "syncSourceHost" : "192.168.198.128:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 1 }, { "_id" : 2, "name" : "192.168.198.128:27019",------(第三台节点) "health" : 1, "state" : 2, "stateStr" : "SECONDARY", ------(从节点) "uptime" : 47, "optime" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1537072188, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2018-09-16T04:29:48Z"), "optimeDurableDate" : ISODate("2018-09-16T04:29:48Z"), "lastHeartbeat" : ISODate("2018-09-16T04:29:53.346Z"), "lastHeartbeatRecv" : ISODate("2018-09-16T04:29:53.725Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "192.168.198.128:27017", "syncSourceHost" : "192.168.198.128:27017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 1 } ], "ok" : 1, "operationTime" : Timestamp(1537072188, 1), "$clusterTime" : { "clusterTime" : Timestamp(1537072188, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }
}
7)到此复制集建立完毕,可是咱们还有一台实例没有添加到复制集中,因此如今演示复制集的添加:
kgcrs:PRIMARY> rs.add("192.168.198.128:27020") ----(添加一台实列到复制集中)
{
"ok" : 1, ----(添加成功)
"operationTime" : Timestamp(1537072738, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1537072738, 2),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
8)有添加,那么就有移除,下面会演示移除的命令:
kgcrs:PRIMARY> rs.remove("192.168.198.128:27020")
{
"ok" : 1, -----(移除成功)
"operationTime" : Timestamp(1537072949, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1537072949, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
9)到这里实验成功,那么须要验证它的功能性,下面会模拟故障转移,在这里是看不出实验效果,只给方法。
[root@localhost ~]# ps aux | grep mongod ---(查看mongod的进程)
root 40778 0.6 6.4 1581996 64908 ? Sl 12:15 0:12 mongod -f /etc/mongod.conf
root 40822 0.6 6.1 1469704 61216 ? Sl 12:17 0:12 mongod -f /etc/mongod2.conf
root 40884 0.7 5.9 1504232 59000 ? Sl 12:18 0:11 mongod -f /etc/mongod3.conf
root 40912 0.5 5.3 1440660 53752 ? Sl 12:19 0:09 mongod -f /etc/mongod4.conf
[root@localhost ~]# kill -9 40778 ----(把进程 kill 掉 ,由于细心的朋友能够看到,40778 如今是主节点,把它 kill 掉,就是为了看其余节点会不会自动切换为主节点)
10)进入第二台实列,查看复制集状态
[root@localhost ~]# mongo --port 27018 ----(进入第二台实例,这里须要跟上端口)
kgcrs:SECONDARY> rs.status() ------(再次查看复制集状态)
{
"set" : "kgcrs",
"date" : ISODate("2018-09-16T04:51:37.669Z"),
"myState" : 2,
"term" : NumberLong(2),
"syncingTo" : "192.168.198.128:27019",
"syncSourceHost" : "192.168.198.128:27019",
"syncSourceId" : 2,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1537073492, 1),
"t" : NumberLong(2)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1537073492, 1),
"t" : NumberLong(2)
},
"appliedOpTime" : {
"ts" : Timestamp(1537073492, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1537073492, 1),
"t" : NumberLong(2)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.198.128:27017", ----(第一台节点)
"health" : 0, ----(原来的健康值变为 “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-16T04:51:36.332Z"),
"lastHeartbeatRecv" : ISODate("2018-09-16T04:47:29.932Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 1, ----(第二台实例)
"name" : "192.168.198.128:27018",
"health" : 1, ----(健康值为 “1”)
"state" : 2,
"stateStr" : "SECONDARY", ----(节点状态是:从几从节点)
"uptime" : 2060,
"optime" : {
"ts" : Timestamp(1537073492, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-09-16T04:51:32Z"),
"syncingTo" : "192.168.198.128:27019",
"syncSourceHost" : "192.168.198.128:27019",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2, -----(第三台节点)
"name" : "192.168.198.128:27019",
"health" : 1, -----(健康值为 ‘1’)
"state" : 1,
"stateStr" : "PRIMARY", -----(如今是第三台节点为主节点)
"uptime" : 1349,
"optime" : {
"ts" : Timestamp(1537073492, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1537073492, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2018-09-16T04:51:32Z"),
"optimeDurableDate" : ISODate("2018-09-16T04:51:32Z"),
"lastHeartbeat" : ISODate("2018-09-16T04:51:36.289Z"),
"lastHeartbeatRecv" : ISODate("2018-09-16T04:51:37.431Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1537073261, 1),
"electionDate" : ISODate("2018-09-16T04:47:41Z"),
"configVersion" : 3
}
],
"ok" : 1,
"operationTime" : Timestamp(1537073492, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1537073492, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
11)从以上数据能够看出,当主节点挂掉后,从节点会自动切换为主节点,可是又不是按照顺序来推荐谁当主节点,这里的推荐的原理,后面会讲到。固然,这里是自动切换主从,咱们也能够手动进行切换
[root@localhost ~]# mongod -f /etc/mongod.conf ----(把上个步骤中止的实例启动起来,方便咱们实验)
[root@localhost ~]# mongo --port 27019 ----(进入主节点服务器,由于咱们须要来进行手动切换主从。)
kgcrs:PRIMARY> rs.freeze(30) ----(暂停30秒不参加选举)
kgcrs:PRIMARY> rs.stepDown(60,30) ----(让主节点交出位子,维持从节点状态很多于60秒,同时等待30秒使主节点和从节点日志同步)
kgcrs:SECONDARY> rs.status() ----(再次查看复制集状态)
12)在从节点默认的状况下,咱们是没法在从节点上读取数据的,只有执行如下命令:
kgcrs:SECONDARY> rs.slaveOk() ----(执行此命令才能够在从节点上读取数据,不然是不容许读取)
1·复制集信息要点说明:health 为 “1” 表明健康,“0” 表明宕机。state 为 “1” 表明主节点,为 “2” 表明从节点
2·在配置实例时须要特别注意修改的数据存储路径,日志存储位子,端口号的修改。
3·复制集最少须要两个节点,这里主节点复制处理客户端请求,从节点复制主节点上的数据
4·它能够实现群集的高可用,当故障时会自动切换,管理员也能够手动切换。
5·在复制集初始化配置时要保证从节点上没有数据。
6·在初始化完复制集参数后,须要经过命令 :rs.initate(cfg) 命令启动复制集。