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

目录

1·MongoDB 复制集概述
2·MongoDB 复制集部署
3·MongoDB 复制集管理(添加、移除等)
4·复制集的总结


MongoDB 复制集是什么?

之前的一片文章讲了 MongoDB 的安装和日常的操作,有兴趣的朋友可以看看 MongoDB 的安装和简单操作



1)什么是复制集?

复制集是额外的一种数据副本,是跨多个服务器同步数据的过程,通俗的说就是可以在不同的服务器上备份数据,专业点说就是冗灾处理。通过复制集可以对硬件和终端的服务进行恢复。



2)复制集的优势如下:

  1-让数据更加安全---(肯定啊,都是备份了,能不安全吗!)
  2-数据的高可用性---(可以全年无休,7*24小时×××)
  3-灾难恢复 ----(不用多说,既然是数据,能没有恢复吗)
  4-无停机维护---(比如说,备份、索引的重建等,MySQL 备份就需要锁定 表 、或者行,而它不会)
  5-读缩放----(额外的副本读取)
  6-它对应用程序是透明的


3)复制集工作原理是什么?

1·既然是一个功能性的东西,那么存在肯定有它的工作原理和过程。MongoDB 的复制集至少需要两个节点,是至少。其中一个是主节点 (Primary),这个主节点主要负责处理客户端的请求,其他的都是从节点 (Secondary),负责复制主节点上的数据。


2·那么我们常用的搭配方式有:一主一丛或一主多从,因为复制集的主从的选举原理是从节点不允许选举为当主节点,但是在实际的生产环境中,主服务器是不可能单点挂上去的,这样要是主服务器挂掉了,那就凉凉。


3·客户端主节点写入数据,在从节点读取数据,主节点与从节点进行数据交互保障数据的统一性。如果其中一个节点出现故障,其他节点马上会把业务接过来而无需停机操作。


4·下图是 MongoDB 复制集结构图





它的特点如下:

N个节点的群集
任何节点可作为主节点
所有写入都是在主节点,读取是在从节点,实现读写分离
自动故障转移
自动恢复


MongoDB 复制集部署

先介绍下环境:CenOS 7.4 上部署
部署前提:安装 MongoDB ,了解什么是实列、和创建多个实例
这里安装 MongoDB 就不再演示。我是直接 YUM 装的。
需要了解 MongoDB 安装 和 多实例的创建 请访问:MongoDB 的安装和命令
需要了解 MongoDB 与 MySQL 的区别 请访问:MySQL - mmm 高可用集群
需要了解 MySQL 的读写分离 请访问:MySQL 主从复制 + 读写分离



1)看多 MongoDB 的多实例创建的知道,创建实例前需要创建数据文件和日志文件存储路径。

[[email protected] ~]# mkdir -p /data/mongodb/mongodb{2,3,4} ----(创建3个数据文件,因为自己 yum 安装了一个,所以也算一个。)


[[email protected] ~]# mkdir -p /data/mongodb/logs ----(创建日志文件路径)
[[email protected] ~]# cd /data/mongodb/logs/
[[email protected] logs]# touch mongodb{2,3,4}.log -----(创建日志文件夹)
[[email protected] logs]# chmod 777 *.log -----(给最大的权限)



2)修改主配置文件 ---- (需要注意的地方用加粗方式显示)

[[email protected] ~]# 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 ,并且修改数据存储路径和日志文件

[[email protected] ~]# cp -p /etc/mongod.conf /etc/mongod2.conf ----(把主配置文件复制一份)


[[email protected] ~]# vim /etc/mongod2.conf -----(修改实列的配置文件)
修改内容如下: ---(修改内容以加粗方式显示)
systemLog:
destination: file
logAppend: true
> path: /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)配置多实例 3、4 (和上一步都是一样,只是数据路径,和日志文件,还有端口号需要修改)

[[email protected] mongodb]# cp -p /etc/mongod2.conf /etc/mongod3.conf
[[email protected] mongodb]# cp -p /etc/mongod2.conf /etc/mongod4.conf
这里就不再分别演示修改方式,会以一张图来说明:修改数据路径、日志文件、端口号



下图是多实例修改样本:



5)当配置文件都 OK 后,就可以把4个实例全部启动:

[[email protected] ~]# mongod -f /etc/mongod.conf ---(第一台实例,是自己用YUM 装的,可以看作一台实例。)


[[email protected] ~]# mongod -f /etc/mongod2.conf ----(第二台实例,需要注意,如果有报错,很大一部分原因都是配置文件有问题,仔细检查配置文件的路径等问题)


[[email protected] ~]# mongod -f /etc/mongod3.conf ----(第三台实例)


[[email protected] ~]# mongod -f /etc/mongod4.conf ----(第4台实例)



6)进入第一台实例,初始化复制集配置 ---(以上步骤只是创建实例,并不是复制集哦。)

[[email protected] ~]# 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)到这里实验成功,那么需要验证它的功能性,下面会模拟故障转移,在这里是看不出实验效果,只给方法。

[[email protected] ~]# 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


[[email protected] ~]# kill -9 40778 ----(把进程 kill 掉 ,因为细心的朋友可以看到,40778 现在是主节点,把它 kill 掉,就是为了看其他节点会不会自动切换为主节点)



10)进入第二台实列,查看复制集状态

[[email protected] ~]# 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)从以上数据可以看出,当主节点挂掉后,从节点会自动切换为主节点,但是又不是按照顺序来推荐谁当主节点,这里的推荐的原理,后面会讲到。当然,这里是自动切换主从,我们也可以手动进行切换

[[email protected] ~]# mongod -f /etc/mongod.conf ----(把上个步骤停止的实例启动起来,方便我们实验)
[[email protected] ~]# 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) 命令启动复制集。

原文地址:http://blog.51cto.com/13746824/2175720

时间: 2024-09-27 23:10:36

【亲测】教你如何搭建 MongoDB 复制集 + 选举原理的相关文章

MongoDB复制集及管理

MongoDB复制集及管理 MongoDB复制集概述 什么是复制集 复制集是额外的数据副本,是跨多个服务器同步数据的过程,复制集提供了冗余并增加了数据可用性,通过复制集可以对硬件故障和中断的服务进行恢复. 复制集的优点如下: 1).让数据更安全:2).高数据可用性:3).灾难恢复:4).无停机恢复(如备份.索引重建.故障转移):5).读缩放(额外的副本读取):6).副本集对应用程序是透明的: 复制集工作原理 MongoDB的复制集至少需要两个节点.其中一个是主节点(Primary),负责处理客户

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

目录: 1·复制与选举的原理与验证2·oplog 日志调整3·配置复制集的优先级4·部署认证的复制5·总结 复制与选举的原理: 上一篇文章搭建了多台实例,部署成复制集,我们能知道复制集的作用,且进行了模拟故障,知道了从节点会主动切换为主节点,那么它是怎么推选出由哪一个从节点担任主节点呢? MongoDB 复制集的节点是通过选举产生主节点的,下面将介绍复制集节点间选举的过程: 1)复制的原理: 复制是基于操作日志 oplog ,相当于 MySQL 中的二进制日志,只会记录发生改变的记录.复制是将主

部署MongoDB复制集(主从复制、读写分离、高可用)

MongoDB 复制集 复制集(Replica Sets)是额外的数据副本,是跨多个服务器同步数据的过程,复制集提供了冗余备份并提高了数据的可用性,通过复制集可以对硬件故障和中断的服务进行恢复. MongoDB 复制集工作原理 mongodb的复制集至少需要两个节点.其中一个是主节点(Primary),负责处理客户端请求,其余的都是从节点(Secondary),负责复制主节点上的数据. mongodb各个节点常见的搭配方式为:一主一从.一主多从.主节点记录其上的所有操作到 oplog 中,从节点

一步一步教你搭建基于docker的MongoDB复制集群环境

一步一步教你搭建基于docker的MongoDB复制集群环境 1.安装docker 2.创建MongoDB的Image 3.搭建MongoDB的集群 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中. 1.ubuntu14.04安装docker 参考文档 http://docs.docker.com/installation/ubuntulinux/ 参考文档 http://docs.docker.com/mac/started/ pc@pc-Th

MongoDB搭建ReplSet复制集群

MongoDB的复制集是一个主从复制模式 又具有故障转移的集群,任何成员都有可能是master,当master挂掉用会很快的重新选举一个节点来充当master. 复制集中的组成主要成员 Primary数据读写 master节点 Secondary备份Primary的数据 默认设置下 不可读 不可写 arbiter投票节点 此节点不会存数据 只参与投票 ,当primary节点出现异常挂掉之后 arbiter节点负责从secondary 节点中选举一个节点升级为Primary节点 其中可以设置Sec

mongodb复制集的实现

复制集(Replica Sets),是一个基于主/从复制机制的复制功能,进行同一数据的异步同步,从而使多台机器拥有同一数据的都多个副本,由于有自动故障转移和恢复特性,当主库宕机时不需要用户干预的情况下自动切换到其他备份服务器上做主库,一个集群最多可以支持7个服务器,并且任意节点都可以是主节点.所有的写操作都被分发到主节点,而读操作可以在任何节点上进行,实现读写分离,提高负载. 资源有限测试一个VM开3个实例: 环境:centos7.0 192.168.1.21:20011 P 192.168.1

MongoDB 复制集节点增加移除及节点属性配置

复制集(replica Set)或者副本集是MongoDB的核心高可用特性之一,它基于主节点的oplog日志持续传送到辅助节点,并重放得以实现主从节点一致.再结合心跳机制,当感知到主节点不可访问或宕机的情形下,辅助节点通过选举机制来从剩余的辅助节点中推选一个新的主节点从而实现自动切换.对于一个已经存在的MongoDB Replica Set集群,可以对其进行节点的增加,删除,以及修改节点属性等等.本文即是围绕这些进行描述. 有关MongoDB复制集概念及其搭建,可以参考:MongoDB 复制集(

MongoDB复制集及数据分片详解

前言 MongoDB是一个由C++语言编写的基于分布式文件存储的数据库,是当前NoSQL数据库中比较热门的一种,旨在为Web应用提供可扩展的高性能数据存储解决方案.本文介绍MongoDB复制集及数据分片. MongoDB 简介 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.支持的数据结构非常松散,因此可以存储比较复杂的数据类型.最大的特点是其支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询

MongoDB复制集原理

版权声明:本文由孔德雨原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/136 来源:腾云阁 https://www.qcloud.com/community MongoDB的单实例模式下,一个mongod进程为一个实例,一个实例中包含若干db,每个db包含若干张表.MongoDB通过一张特殊的表local.oplog.rs存储oplog,该表的特点是:固定大小,满了会删除最旧记录插入新记录,而且只支持append操作,因