MongoDB 复制集 第 二 部 之选举原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB 复制集 第 二 部 之选举原理相关的知识,希望对你有一定的参考价值。

目录:

1·复制与选举的原理与验证
2·oplog 日志调整
3·配置复制集的优先级
4·部署认证的复制
5·总结


复制与选举的原理:

上一篇文章搭建了多台实例,部署成复制集,我们能知道复制集的作用,且进行了模拟故障,知道了从节点会主动切换为主节点,那么它是怎么推选出由哪一个从节点担任主节点呢?


MongoDB 复制集的节点是通过选举产生主节点的,下面将介绍复制集节点间选举的过程:


1)复制的原理:

复制是基于操作日志 oplog ,相当于 mysql 中的二进制日志,只会记录发生改变的记录。复制是将主节点的 oplog 日志同步并应用到其他的从节点的过程。


2)选举的原理:

节点类型分为标准(host)节点、被动(passive)节点和仲裁(arbiter)节点。


(1)只有标准节点肯被选举为活跃节点,由选举权。被动节点由完整副本,不可能成为活跃节点,由选举权。仲裁节点不复制数据,不能成为活跃节点,只有选举权。


(2)标准节点与被动节点的区别:priority 值高者是标准节点,低者为被动节点


(3)选举规则是票数高的获胜,priority 是优先权为 0 ~ 1000 的值,相当于额外增加 0 ~ 1000 的票数。选举结果:票数高的获胜,若票数相同,数据新者获胜。


MongoDB 复制集节点选举如下图:
技术分享图片


验证复制集选的举原理

实验说明:CenOS 7.4 上部署好复制集,在上篇文章讲解了复制集的部署,由兴趣的朋友可以去看看:MongoDB 复制集部署,那么这里将直接开始验证复制集选举原理,部署就不再演示。


1)配置复制集的优先级,重新定义复制集的参数:

重新配置4个节点的 MongoDB 复制集,设置两个标准节点,一个被动节点和一个仲裁节点。


[[email protected] ~]# mongo
cfg={"_id":"kgcrs","members":[{"_id":0,"host":"192.168.198.128:27017","priority":100}----(标准节点),{"_id":1,"host":"192.168.198.128:27018","priority":100}-----(标准节点),{"_id":2,"host":"192.168.198.128:27019","priority":0}--(被动节点),{"_id":3,"host":"192.168.198.128:27020","arbiterOnly":true}]}---(仲裁节点


kgcrs:PRIMARY> rs.reconfig(cfg) -----(从新定义cfg参数)
{
"ok" : 1, -----(定义成功)
"operationTime" : Timestamp(1537079319, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1537079319, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}


kgcrs:PRIMARY> rs.isMaster() ----(查看状态)


{
"hosts" : [
"192.168.198.128:27017",------(两台标准节点)
"192.168.198.128:27018"
],
"passives" : [
"192.168.198.128:27019"-----(一个被动节点)
],
"arbiters" : [
"192.168.198.128:27020"-----(一个仲裁节点),
"setName" : "kgcrs",
"setVersion" : 4,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.198.128:27017",


2)模拟主节点故障,看看另一个标准节点是否会选举成为新的主节点

[[email protected] ~]# mongod -f /etc/mongod.conf --shutdown ----(关闭主节点)
[[email protected] ~]# mongo --port 27018 ----(进入任意节点)
kgcrs:SECONDARY> rs.status() -----(查看节点状态)


"_id" : 1,
"name" : "192.168.198.128:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY", ----(切换为主节点)
"uptime" : 3112,
"optime" : {
"ts" : Timestamp(1537081092, 1),
"t" : NumberLong(6)


结论:当主节点为第一个标准节点出现故障后,MongoDB 复制集会选举第二个标准节点为主节点


3)模拟所有标准节点出现故障

[[email protected] ~]# mongod -f /etc/mongod.conf --shutdown --(停止第一台标准节点)
[[email protected] ~]# mongod -f /etc/mongod2.conf --shutdown --(停止第二台标准节点)


[[email protected] ~]# mongo --port 27019 ---(进入被动节点)
kgcrs:SECONDARY> rs.status() ---(查看节点状态)


"_id" : 2,
        "name" : "192.168.198.128:27019", ----(被动节点)
        "health" : 1,
        "state" : 2, -----(依旧是丛节点)
        "stateStr" : "SECONDARY",
        "uptime" : 302,
        "optime" : {
            "ts" : Timestamp(1537081537, 1),
            "t" : NumberLong(7)
        },
        "optimeDate" : ISODate("2018-09-16T07:05:37Z"),
        "syncingTo" : "",
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "infoMessage" : "could not find member to sync from",
        "configVersion" : 4,
        "self" : true,
        "lastHeartbeatMessage" : ""

结论:说明无论如何,即使标准节点都出现故障,被动节点都不会成为主节点


kgcrs:SECONDARY> rs.printSlaveReplicationInfo() ---(查看复制集状态)
rs.printReplicationInfo() ----(查看 oplog 日志文件可存储大小)


kgcrs:SECONDARY> rs.printSlaveReplicationInfo()
source: 192.168.198.128:27018
syncedTo: Sun Sep 16 2018 15:15:00 GMT+0800 (CST)
0 secs (0 hrs) behind the primary ----(状态为主)
source: 192.168.198.128:27019
syncedTo: Sun Sep 16 2018 15:15:00 GMT+0800 (CST)
0 secs (0 hrs) behind the primary
kgcrs:SECONDARY> rs.printReplicationInfo()
configured oplog size: 990MB ---(可存储的大小为990M)
log length start to end: 9994secs (2.78hrs)
oplog first event time: Sun Sep 16 2018 12:29:06 GMT+0800 (CST)
oplog last event time: Sun Sep 16 2018 15:15:40 GMT+0800 (CST)
now: Sun Sep 16 2018 15:15:46 GMT+0800 (CST)


更改oplog 日志存储大小

为什么要修改 oplog 日志的大小?
在 MongoDB 复制的过程中,主节点会把操作记录到 oplog 里,就像MySQL 的二进制日志,从节点复制这些oplog ,但是这些操作是异步的,为了避免因为 oplog 的大小问题而使从节点重新做完整的同步,就需要尽量保证主机点的 oplog 足够大。


1) 这里因为是实验,在生产环境中,这个应该部署在前。首先停掉所有的节点,因为这里需要修改配置文件。


[[email protected] ~]# mongod -f /etc/mongod.conf --shutdown
killing process with pid: 45106
[[email protected] ~]# mongod -f /etc/mongod2.conf --shutdown
killing process with pid: 45322
[[email protected] ~]# mongod -f /etc/mongod3.conf --shutdown
killing process with pid: 44788
[[email protected] ~]# mongod -f /etc/mongod4.conf --shutdown
killing process with pid: 45193


[[email protected] ~]# vim /etc/mongod.conf ---(修改配置文件)


内容如下
net:
port: 37017 ----(修改端口号)
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.

#security:

#operationProfiling:

#replication:
#replSetName: kgcrs ----(把复制集都注释掉)


相当于把这台节点踢出复制集,然后重启这台节点服务器。并且进入重新建立日志文件大小


[[email protected] ~]# mongod -f /etc/mongod.conf ----(重启节点服务器)
[[email protected] ~]# mongo --port 37017 ---(进入MongoDB ,现在相当于一台独立的服务器)


use local() ---(进入local 数据库中)
db.oplog.rs.drop() ----(删除原有的日志)
db.runCommand({create:"oplog.rs",capped:true,size:(210241024*1024)}) -----从新建立日志文件大小为2G
{ "ok" : 1 }


再次修改主配置文件:

[[email protected] ~]# mongod -f /etc/mongod.conf --shutdown ---(关闭服务器)
[[email protected] ~]# vim /etc/mongod.conf ----(修改配置文件)


修改内容如下:
net:
port: 27017
bindIp: 0.0.0.0 # Listen to local interface only, comment to listen on all interfaces.

#security:

#operationProfiling:

replication: ----(去掉注释)
replSetName: kgcrs ----(去掉注释)
oplogSizeMB:2048 ----(必须把这段话加入,格式需要对齐)


再次启动节点服务器,相当于再次添加到复制集中

[[email protected] ~]# mongod -f /etc/mongod.conf ----(重启服务)
[[email protected] ~]# mongo ----(进入服务,再次查看日志大小)


kgcrs:PRIMARY> rs.printReplicationInfo() ---查看日志大小


configured oplog size: 2048MB -----(大小改变为2G)
log length start to end: 1930secs (0.54hrs)
oplog first event time: Sun Sep 16 2018 15:33:30 GMT+0800 (CST)
oplog last event time: Sun Sep 16 2018 16:05:40 GMT+0800 (CST)
now: Sun Sep 16 2018 16:05:46 GMT+0800 (CST)


最好是每个节点都修改,这里就不再演示其他节点。下面是介绍部署认证的复制也就是身份验证,不如MySQL 登陆时都需要密码,可是 MongoDB 登陆时时不需要的,但是为安全,我们需要加上身份验证

kgcrs:PRIMARY> use admin ---(进入admin 数据库)
kgcrs:PRIMARY> db.createUser({"user":"root","pwd":"123","roles":["root"]})
Successfully added user: { "user" : "root", "roles" : [ "root" ] } ----(创建root用户,使用密码123登陆)


[[email protected] ~]# vim /etc/mongod.conf ---(修改配置文件,其他节点都需要修改)


修改内容如下:
security:
keyFile: /usr/bin/kgcrskey1
clusterAuthMode:keyFile


生成4个实例的密钥文件
[[email protected] ~]# cd /usr/bin/
[[email protected] bin]# echo "kgcrs key" > kgcrskey1
[[email protected] bin]# echo "kgcrs key" > kgcrskey2
[[email protected] bin]# echo "kgcrs key" > kgcrskey3
[[email protected] bin]# echo "kgcrs key" > kgcrskey4


修改文件权限,重启所有实例 ----(这里演示一个实例)
[[email protected] bin]# chmod 600 /usr/bin/kgc* ---(修改权限为 600)
[[email protected] bin]# mongod -f /etc/mongod.conf --shutdown ---(重启实列)

这里每个节点都需要修改配置文件、如上操作,然后重启。


验证身份登陆:
[[email protected] bin]# mongo ---(登陆服务器)
kgcrs:PRIMARY> use admin ---(进入admin数据库)
switched to db admin
kgcrs:PRIMARY> db.auth("root","123") ----(使用root身份登陆,登陆密码是:123)
1


总结:

1· MongoDB 的复制是依靠 oplog 日志 ,相当于MySQL 的二进制日志文件,MySQL的备份就需要二进制日志文件,道理相同,它只记录发生改变的记录。将主节点的 oplog 日志同步并应用到其他从节点的过程就是复制


2·节点的类型:标准节点、被动节点和仲裁节点,只有标准节点可能被选举为主节点


3·尽量保证主节点的oplog足够大,能够存放相当长或容量的数据。

以上是关于MongoDB 复制集 第 二 部 之选举原理的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB复制选举原理及复制集管理

MongoDB复制集选举原理管理

亲测教你如何搭建 MongoDB 复制集 + 选举原理

『MongoDB』MongoDB部署架构——复制集篇(Replica Set)

MongoDB复制集管理优化

MongoDB 复制集