Percona MongoDB 4 搭建副本集
什么是副本集:
- 是一组维护相同数据集的mongod进程
- 提供冗余,自动故障转移和高可用性
- 提供读取可伸缩性
- 内部概念或多或少与MySQL的概念相似
- PRIMARY概念与MySQL复制中的MASTER大致相同
- SECONDARY概念与MySQL复制中的SLAVE大致相同。
- 数据复制是异步的,就像在MySQL中一样。我们不确定辅助设备是否与主设备保持同步。但是在MongoDB中,我们可以在写操作上定义“写问题”来定义需要什么类型的确认。例如,我们可以定义一个写入需要确认是否至少有一个辅助节点已经应用了该文档,或者我们甚至可以要求所有辅助节点都需要是最新的。
- 在读取oplog的节点之间复制数据,这是一个包含修改和插入文档的特殊上限集合。这个概念类似于MySQL binlog,但它们的工作方式不同。oplog的一个特点是它内部的每个操作都是幂等的。这意味着即使应用一次或多次,oplog操作也会产生相同的结果。例如,您不能删除两次。如果您再次应用相同的删除操作,那将是一个无操作。插入和更新也是如此。
- 由于oplog是数据库中的集合,我们可以轻松地查询它。oplog的内容是在系统的每个集合上插入或更新的文档。由于oplog是一个上限集合,因此它具有固定且可配置的大小。因此,oplog的大小也表示我们过去可以为事件花多长时间。作为一个粗略的例子:如果我们的数据库每天总共1GB插入,更新或删除文档,拥有3GB的oplog意味着我们可以存储或多或少三天的事件。
副本集的工作原理
下图显示了应用程序查询三节点副本集的典型环境。

在正常操作期间,副本集只有一个节点作为PRIMARY而所有其他节点都是SECONDARY。PRIMARY成员是唯一接收写入的成员。它更新其本地集合和文档以及oplog。然后,oplog事件通过复制通道发送到所有SECONDARY节点。每个SECONDARY节点在本地和异步上应用对本地数据和oplog的相同修改。
下图在内部显示了副本集的工作原理。每个节点都连接到所有其他节点,并且有一个心跳机制来ping任何其他节点。心跳具有用于ping节点的可配置时间,默认值为10秒。

如果所有节点都响应心跳确认,则群集继续工作。如果其中一个节点崩溃,例如PRIMARY(最坏的情况),则发生涉及剩余节点的选举。
当SECONDARY在配置的超时后没有收到对心跳的响应时,它会要求进行选举。仍然存活的节点投票支持新的PRIMARY。选举阶段通常不需要很长时间,选举算法足够复杂,让他们选择最佳的次要成为新的主要。让我们说这是次要的,与死亡的初级主要是最新的。
除了主要崩溃之外,还有一些节点要求进行选举的情况:将节点添加到副本集时,在“启动副本集”期间或在某些维护活动期间。这种选举不是本文的目的。
副本集在选举成功完成之前无法处理写入操作,但如果将此类查询配置为在辅助节点上运行,则可以继续提供读取查询(稍后我们将对此进行讨论)。选举正确完成后,群集将恢复正常操作。
要正常工作,副本集需要具有奇数个成员。在网络分裂的情况下,只有奇数个成员确保我们在其中一个子集中拥有大多数投票。在具有大多数节点的子集中选择新的PRIMARY。
因此,三个是副本集的最小节点数,以确保高可用性。
仲裁节点
由于每个节点都需要拥有完整的数据副本,因此如果您拥有庞大的数据库,则需要提供至少三台具有大量磁盘,内存和CPU资源的计算机。这可能很昂贵。
幸运的是,您可以将其中一个节点配置为Arbiter,这是一个不复制数据的特殊成员。它是空的,但它可以在选举期间投票。
使用仲裁节点是维持奇数成员的一个很好的解决方案,而不需要花费很多钱来使第三个节点像其他节点一样强大。仲裁节点不能被选为新主节点,因为它没有数据。

环境
| ip | 主机名 | 系统 |
|---|---|---|
| 172.18.11.142 | nodejs1 | Centos 7.6 |
| 172.18.11.143 | nodejs2 | Centos 7.6 |
| 172.18.11.144 | nodejs3 | Centos 7.6 |
安装
# 下载安装包并安装
mkdir -p /opt/mongodb/
cat <<EOF > /opt/mongodb/mongodb_down.sh
cd /opt/mongodb/
wget https://www.percona.com/downloads/percona-server-mongodb-LATEST/percona-server-mongodb-4.0.9-4/binary/redhat/7/x86_64/percona-server-mongodb-shell-4.0.9-4.el7.x86_64.rpm
wget https://www.percona.com/downloads/percona-server-mongodb-LATEST/percona-server-mongodb-4.0.9-4/binary/redhat/7/x86_64/percona-server-mongodb-mongos-4.0.9-4.el7.x86_64.rpm
wget https://www.percona.com/downloads/percona-server-mongodb-LATEST/percona-server-mongodb-4.0.9-4/binary/redhat/7/x86_64/percona-server-mongodb-tools-4.0.9-4.el7.x86_64.rpm
wget https://www.percona.com/downloads/percona-server-mongodb-LATEST/percona-server-mongodb-4.0.9-4/binary/redhat/7/x86_64/percona-server-mongodb-server-4.0.9-4.el7.x86_64.rpm
wget https://www.percona.com/downloads/percona-server-mongodb-LATEST/percona-server-mongodb-4.0.9-4/binary/redhat/7/x86_64/percona-server-mongodb-4.0.9-4.el7.x86_64.rpm
EOF
bash -x /opt/mongodb/mongodb_down.sh
yum localinstall /opt/mongodb/*.rpm -y
systemctl enable mongod
主机名
cat <<EOF >> /etc/hosts
192.168.0.249 k8s-m1
192.168.0.250 k8s-n1
192.168.0.251 k8s-n2
EOF
配置文件
cat <<EOF > /etc/mongod.conf
storage:
dbPath: /var/lib/mongo
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongo/mongod.log
processManagement:
fork: true
pidFilePath: /var/run/mongod.pid
net:
port: 27017
bindIp: 0.0.0.0
EOF
启动
systemctl start mongod
副本集的名称
副本集的名称这里使用 rs-smy,将副本集名称放置于每一台主机的 /etc/mongod.conf
replication:
replSetName: "rs-smy"
重启所有服务器
systemctl restart mongod
初始化集群
随便连接到一个节点,发出 rs.initiate() 让副本集直到有哪些成员
rs.initiate( {
_id: "rs-smy",
members: [
{ _id: 0, host: "172.18.11.142:27017" },
{ _id: 1, host: "172.18.11.143:27017" },
{ _id: 2, host: "172.18.11.144:27017" }
] })
发出命令后,MongoDB使用默认配置启动复制过程。选择PRIMARY节点,现在将创建的所有文档将在SECONDARY节点上异步复制。
我们可以通过查看mongo shell提示符来验证复制是否正常。一旦副本集启动并运行,提示应该在PRIMARY节点上如下:
rs-smy:PRIMARY>
在SECONDARY节点上这样:
rs-test:SECONDARY>
一些有用的命令
有几个命令可以调查并在副本集上执行一些管理任务。这里有几个。
要调查副本集配置,您可以在任何节点上发出rs.conf()
rs-smy:SECONDARY> rs.conf()
{
"_id" : "rs-smy",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "172.18.11.142:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "172.18.11.143:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "172.18.11.144:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5ce54845de4f73c1e97ea042")
}
}
我们可以看到有关已配置节点的信息,无论是仲裁还是隐藏,优先级以及有关心跳过程的其他详细信息。
要调查副本集状态,您可以在任何节点上发出rs.status()
s-smy:SECONDARY> rs.status()
{
"set" : "rs-smy",
"date" : ISODate("2019-05-23T10:12:44.663Z"),
"myState" : 2,
"term" : NumberLong(7),
"syncingTo" : "172.18.11.144:27017",
"syncSourceHost" : "172.18.11.144:27017",
"syncSourceId" : 2,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"appliedOpTime" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"durableOpTime" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1558606350, 1),
"members" : [
{
"_id" : 0,
"name" : "172.18.11.142:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 24733,
"optime" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"optimeDate" : ISODate("2019-05-23T10:12:40Z"),
"syncingTo" : "172.18.11.144:27017",
"syncSourceHost" : "172.18.11.144:27017",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "172.18.11.143:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 24523,
"optime" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"optimeDurable" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"optimeDate" : ISODate("2019-05-23T10:12:40Z"),
"optimeDurableDate" : ISODate("2019-05-23T10:12:40Z"),
"lastHeartbeat" : ISODate("2019-05-23T10:12:44.463Z"),
"lastHeartbeatRecv" : ISODate("2019-05-23T10:12:44.448Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "172.18.11.144:27017",
"syncSourceHost" : "172.18.11.144:27017",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "172.18.11.144:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 24519,
"optime" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"optimeDurable" : {
"ts" : Timestamp(1558606360, 1),
"t" : NumberLong(7)
},
"optimeDate" : ISODate("2019-05-23T10:12:40Z"),
"optimeDurableDate" : ISODate("2019-05-23T10:12:40Z"),
"lastHeartbeat" : ISODate("2019-05-23T10:12:44.464Z"),
"lastHeartbeatRecv" : ISODate("2019-05-23T10:12:44.433Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1558594808, 1),
"electionDate" : ISODate("2019-05-23T07:00:08Z"),
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1558606360, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1558606360, 1),
"signature" : {
"hash" : BinData(0,"eo6zfAdAzzCTw/rQj+OWbd7Vots="),
"keyId" : NumberLong("6693835933885661186")
}
}
}
可以看到哪个是PRIMARY,哪个是SECONDARY
测试复制
连接到PRIMARY节点并创建例子:
rs-smy:PRIMARY> use test
switched to db test
rs-test:PRIMARY> db.foo.insert( {name:"Bruce", surname:"Dickinson"} )
WriteResult({ "nInserted" : 1 })
rs-smy:PRIMARY> db.foo.find().pretty()
{
"_id" : ObjectId("5ae05ac27e6680071caf94b7")
"name" : "Bruce"
"surname" : "Dickinson"
}
然后连接到SECONDARY节点并查找相同的文档。
请记住,您无法连接到SECONDARY节点以读取数据。默认情况下,只允许在PRIMARY上进行读写操作。因此,如果要读取SECONDARY节点上的数据,首先需要发出rs.slaveOK()命令。如果您不这样做,您将收到错误。
rs-test:SECONDARY> rs.slaveOK()
rs-test:SECONDARY> show collections
local
<strong>foo</strong>
rs-test:SECONDARY> db.foo.find().pretty()
{
"_id" : ObjectId("5ae05ac27e6680071caf94b7")
"name" : "Bruce"
"surname" : "Dickinson"
}
SECONDARY节点已经复制了集合foo和插入文档的创建。
Percona MongoDB 4 搭建副本集的更多相关文章
- MongoDB集群搭建-副本集
MongoDB集群搭建-副本集 概念性的知识,可以参考本人博客地址: 一.Master-Slave方案: 主从: 二.Replica Set方案: 副本集: 步骤:(只要按步骤操作,100%成功) 1 ...
- MongoDB 搭建副本集
副本集(Replica Set)是一组MongoDB实例组成的集群,由一个主(Primary)服务器和多个备份(Secondary)服务器构成.通过Replication,将数据的更新由Primary ...
- MongoDB主从复制和副本集
MongoDB有主从复制和副本集两种主从复制模式,主从复制最大的问题就是无法自动故障转移,MongoDB副本集解决了主从模式无法自动故障转义的特点,因此是复制的首选.对于简单的主从复制无法自动故障转移 ...
- MongoDB-3.4搭建副本集
搭建副本集 1:首先创建3台虚拟机作为配置环境 IP1:192.168.101.175 IP2:192.168.101.176 IP3:192.168.101.177 2.下载MongoDB 3.4版 ...
- 【六】MongoDB管理之副本集
一.复制介绍 所谓的复制就是在多个主机之间同步数据的过程. 1.数据冗余及可用性 复制技术提供数据冗余及可用性,在不同的数据库服务器上使用多个数据副本,复制技术防止单个数据库服务器出现数据故障而出现数 ...
- MongoDB 复制(副本集)学习
MongoDB 复制(副本集)学习 replication set复制集,复制集,多台服务器维护相同的数据副本,提高服务器的可用性.MongoDB复制是将数据同步在多个服务器的过程.复制提供了数据的冗 ...
- mongodb 4.0副本集搭建
近期有同学问mongodb副本集难不难部署,我的回答是不难,很快,几分钟搞定,比mysql MHA简单的不止一点半点. 那么到底如何部署呢?请看下文. 1. 准备工作 1.1 下载软件 选择版本并下 ...
- mongodb安装及副本集搭建
mongodb下载地址:https://www.mongodb.com/dr/fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.2.7.tg ...
- MongoDB 副本集搭建 & 副本集扩容
副本集的搭建 创建多实例目录 [root@redis03 ~]# mkdir /server/mongodb/2801{7,8,9}/{conf,logs,pid,data} -p 编辑多实例配置文件 ...
随机推荐
- Nginx+FastCGI到底是谁影响超时时间
需求: 一个php程序要跑一段时间,但是时间不确定. 问题: 当该php程序运行超过一段时间被强制断开连接. PHP本身超时处理 在 php.ini 中,有一个参数 max_execution_tim ...
- 导出设计文档总结 plantUML Graphviz jacob
plantUML https://blog.csdn.net/HelloWorld998/article/details/90676496 http://skyao.github.io/2014/12 ...
- Python 面向对象(上)
一. 什么是面向对象? 1. 在了解面向对象之前,首先我们需要知道两个概念:(1)什么是函数?函数是对功能或动作的一种封装.函数的语法结构如下: def func(arg1): '''函数的内部有函数 ...
- 想了解Java后端学习路线?你只需要这一张图!
前言 学习路线图往往是学习一样技术的入门指南.网上搜到的Java学习路线图也是一抓一大把. 今天我只选一张图,仅此一图,足以包罗Java后端技术的知识点.所谓不求最好,但求最全,学习Java后端的同学 ...
- CenterNet算法笔记(目标检测论文)
论文名称:CenterNet: Keypoint Triplets for Object Detectiontection 论文链接:https://arxiv.org/abs/1904.08189 ...
- 并查集 --cogs456 岛国
题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=pNyNQiqge 思路: 基础是并查集,将两个相邻的岛算作一个集合,每次若合并成功,则N ...
- 使用vue-lbsmap快速开发地图应用/GPSBD
vue-lbsmap是一款基于vue的WebGIS地图插件,经过我们多年实际项目应用中积累的技术,打造的灵活.易用.数据驱动型插件,可以帮助您快速开展地图业务层的应用开发,完全免费 <!DOCT ...
- Springboot使用launch.script打包后解压缩
今天拿到一个SpringBoot的jar需要反编译看一下.直接用工具试了下提示报错. 于是用文本工具打开看了下,发现此JAR包在打包时候引入了启动脚本.如下图: 为了反编译,可以直接将所有启动脚本相关 ...
- Postfix to Prefix Conversion & Prefix to Postfix Conversion
Postfix to Prefix Conversion Postfix: An expression is called the postfix expression if the operator ...
- C++命名建议
如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套统一.带层次结构.清晰明了的命名准则就是必不可少而且非常好用的工具. 活跃在生物学.化学.军队.监狱.黑社会.恐怖组织等各个领域内的大量有识 ...