- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章MongoDB添加secondary节点的2种方法详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
前段时间维护的一个事业群的其中一条业务线的开发找到运维,提出来了一个MongoDB的优化问题,那段时间MongoDB正在从op管理移交给db进行维护,整个部门都对MongoDB的运维经验缺乏,MongoDB的优化更是一个未知的挑战。当op找到我,核心系统的公共服务平台用来进行短信服务的MongoDB集群想进行一次优化,我当仁不能让的承担了这项我都觉得可能搞不定的任务.
开发找到我提出了两点儿问题,并寻求运维团队解决这个问题,不过最终在我的理性的思考和他感性的思维碰撞下,最终我还是以胜利者的姿态胜出。我成功说服了他,并解答了他一些疑问,得到了满意的答复后再也没找我了。当然这里肯定不会就凭几句话,任你理论再怎么丰富,态度如何暧昧,不拿点儿真实数据,做点儿什么,怎么能说服经验丰富的开发认定的事儿。沟通了大半天,占据了我白天的工作时间,不过他提出来的问题还是很值得讨论.
根据开发的逻辑,是想横向扩充secondary节点,把其他要求不高的业务放到secondary节点上,减轻primary节点的压力,达到部分读写分离,使得主要业务优先保障。我觉得这个出发点是好的,但并没有就此作出回应,其一是他没有认识到这个他认为的有延迟并不是数据库集群的问题(这里不详细讲述排查的过程,下一篇文章会讲些MongoDB的写入与业务逻辑),其二是我们确实缺乏有效的资源硬件去进行扩充节点.
不同的业务场景应用不同的架构策略,扩充secondary节点有时候不能解决问题,尤其是那些实时性很高的业务,但有时候扩充secondary节点确实有效,比如硬件升级后需要做的服务迁移,需要在线扩充secondary节点来满足业务需要的更高的硬件要求.
MongoDB的secondary节点的扩充,我总结起来有两种方式:
1、rs.add()直接扩充 。
2、一致性备份后进行扩充(个人叫法) 。
1、rs.add("HOST_NAME:PORT") 。
具体的实现方式是登陆扩充节点的机器,编辑好配置文件,并建立相应的目录和权限,启动MongoDB实例就可以了.
需要注意的一点儿是这种扩充方式要保证同步源的数据量级,即保证在同步完数据前MongoDB的oplog不会被覆盖,这点儿类似与MySQL的redo log日志,如果被覆盖那么同步的数据出现不一致,导致同步失败.
需要注意的另一点是同步数据的过程中,当集群数据达到一定量级时,同步数据的大小很大就会对网络造成一定的压力,可能对业务的核心交换机造成影响,因此需要用TC工具对同步流量做限速处理。这个限速需要考虑同步源可能不会是primary,也可能是同样角色的secondary节点,令外限速同步势必会增大同步时间,这个会增大oplog被覆盖的概率,具体限速值还是要经过计算才能把握好.
2、一致性快照快速添加secondary节点(自我命名,欢迎各位交流) 。
a)primary节点上进行一致性快照备份 。
b)secondary节点上进行一致性快照恢复,仅仅对数据部分进行恢复,暂时不要对oplog进行恢复 。
c)初始化oplog.rs集合,并恢复oplog记录 。
d)初始化local数据库的其他两个集合db.replset.election,db.system.replset 。
e)修改数据库配置并重启数据库(这一步操作前实例不开启认证模式、复制集的配置),rs.add("HOST_NAME:PORT")将secondary添加进集群并观察同步状态、校验数据的完整和一致性 。
实践的详细实践过程如下(仅供参考交流,生产环境慎用):
1、primary上进行一致性快照备份 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#primary节点或者其他secondary节点备份数据
[root@172-16-3-190 mongodb]
# /opt/app/mongodb/bin/mongodump -uroot -ppwd4mysql --authenticationDatabase=admin --port=27017 --oplog -o /tmp/dump_mongo/
2018-08-20T15:42:47.028+0800 writing admin.system.
users
to
2018-08-20T15:42:47.030+0800
done
dumping admin.system.
users
(1 document)
2018-08-20T15:42:47.030+0800 writing admin.system.version to
2018-08-20T15:42:47.031+0800
done
dumping admin.system.version (2 documents)
2018-08-20T15:42:47.032+0800 writing super_hero.user_address to
2018-08-20T15:42:47.032+0800 writing super_hero.user_info to
2018-08-20T15:42:47.033+0800
done
dumping super_hero.user_address (1 document)
2018-08-20T15:42:47.033+0800
done
dumping super_hero.user_info (1 document)
2018-08-20T15:42:47.034+0800 writing captured oplog to
2018-08-20T15:42:47.036+0800 dumped 1 oplog entry
#查看备份的文件
[root@172-16-3-190 mongodb]
# ls -lh /tmp/dump_mongo/
total 12K
drwxr-xr-x 2 root root 4.0K Aug 20 15:42 admin
-rw-r--r-- 1 root root 110 Aug 20 15:42 oplog.bson
drwxr-xr-x 2 root root 4.0K Aug 20 15:42 super_hero
#传递备份到准备添加为secondary的节点上
[root@172-16-3-190 tmp]
# scp -r -P22222 /tmp/dump_mongo/ liyingxiao@172.16.3.189:/tmp
|
2、secondary节点一致性快照恢复 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#auth=true
#replSet = repl_mongo
#clusterAuthMode=keyFile
#keyFile=/opt/app/mongodb/keyfile/mongodb.key
##恢复数据
[root@172-16-3-189 we_ops_admin]
# /opt/app/mongodb/bin/mongorestore --oplogReplay --port=27017 /tmp/dump_mongo/
2018-08-20T15:56:32.161+0800 preparing collections to restore from
2018-08-20T15:56:32.193+0800 reading metadata
for
super_hero.user_info from
/tmp/dump_mongo/super_hero/user_info
.metadata.json
2018-08-20T15:56:32.194+0800 reading metadata
for
super_hero.user_address from
/tmp/dump_mongo/super_hero/user_address
.metadata.json
2018-08-20T15:56:32.222+0800 restoring super_hero.user_address from
/tmp/dump_mongo/super_hero/user_address
.bson
2018-08-20T15:56:32.300+0800 restoring super_hero.user_info from
/tmp/dump_mongo/super_hero/user_info
.bson
2018-08-20T15:56:32.867+0800 no indexes to restore
2018-08-20T15:56:32.867+0800 finished restoring super_hero.user_address (1 document)
2018-08-20T15:56:32.881+0800 no indexes to restore
2018-08-20T15:56:32.881+0800 finished restoring super_hero.user_info (1 document)
2018-08-20T15:56:32.881+0800 restoring
users
from
/tmp/dump_mongo/admin/system
.
users
.bson
2018-08-20T15:56:32.993+0800 replaying oplog
2018-08-20T15:56:32.997+0800
done
|
3、初始化oplog.rs集合,并恢复oplog记录 。
创建oplog.rs集合并初始化大小 。
1
2
|
use
local
db.createCollection(
"oplog.rs"
,{
"capped"
:
true
,
"size"
:100000000})
|
恢复一致性备份的oplog.rs集合的数据到secondary节点 。
1
2
3
4
5
6
|
[root@172-16-3-189 we_ops_admin]
# /opt/app/mongodb/bin/mongorestore -d local -c oplog.rs --port=27017 /tmp/dump_mongo/oplog.bson
2018-08-20T16:12:49.848+0800 checking
for
collection data
in
/tmp/dump_mongo/oplog
.bson
2018-08-20T16:12:49.852+0800 restoring
local
.oplog.rs from
/tmp/dump_mongo/oplog
.bson
2018-08-20T16:12:49.925+0800 no indexes to restore
2018-08-20T16:12:49.925+0800 finished restoring
local
.oplog.rs (1 document)
2018-08-20T16:12:49.925+0800
done
|
4、初始化db.replset.election,db.system.replset集合,其中replset.election需要查询主节点数据并将这些数据存储到secondary节点,或者两个结合自行save到secondary节点。另集合system.replset加入复制集后可自动识别primary节点内容(这里我采取自行同步数据) 。
1
2
3
4
5
|
#primary节点
repl_mongo:PRIMARY> db.replset.election.
find
()
{
"_id"
: ObjectId(
"5b7a6ee5de7a24b82a686139"
),
"term"
: NumberLong(1),
"candidateIndex"
: NumberLong(0) }
#secondary节点
db.replset.election.save({
"_id"
: ObjectId(
"5b7a6ee5de7a24b82a686139"
),
"term"
: NumberLong(1),
"candidateIndex"
: NumberLong(0) })
|
5、修改数据库配置并重启,添加secondary节点到复制集群中 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#auth=true
#replSet = repl_mongo
#clusterAuthMode=keyFile
#keyFile=/opt/app/mongodb/keyfile/mongodb.key
[root@172-16-3-189 we_ops_admin]
# /opt/app/mongodb/bin/mongod --shutdown -f /opt/app/mongodb/mongo.conf
killing process with pid: 5331
[root@172-16-3-189 we_ops_admin]
# vim /opt/app/mongodb/mongo.conf #注释去掉并重启
[root@172-16-3-189 we_ops_admin]
# /opt/app/mongodb/bin/mongod -f /opt/app/mongodb/mongo.conf
about to fork child process, waiting
until
server is ready
for
connections.
forked process: 5722
child process started successfully, parent exiting
#添加secondary节点
repl_mongo:PRIMARY> rs.add({
"_id"
:1,
"host"
:
"172.16.3.189:27017"
})
{
"ok"
: 1,
"operationTime"
: Timestamp(1534752953, 1),
"$clusterTime"
: {
"clusterTime"
: Timestamp(1534752953, 1),
"signature"
: {
"hash"
: BinData(0,
"Tt9nzhoVYdUtGFZnc1Kg1exl0Hc="
),
"keyId"
: NumberLong(
"6591702943026642945"
)
}
}
}
|
6、登录添加的secondary节点,验证复制集状态,数据完整和一致性.
1
|
[root@172-16-3-189 we_ops_admin]
# /opt/app/mongodb/bin/mongo -uroot -ppwd4mysql --authenticationDatabase=admin --port=27017
|
重点介绍第二种省时省心但费力费操作的添加secondary节点的方法,实践过程中数据库实例前期去掉认证和复制集参数,是方便我们下面的一些需要用户权限的操作,避免建立管理员账号,后续加入集群后自行同步了primary节点的账号。重启后登录secondary节点验证服务的可用性和数据一致性时,使用集群的管理账号进入,否则会报认证的错误.
总结如上两种扩充方式,对于方式1的扩充简单省事,需要保证oplog不被覆盖和评估同步流量的影响问题,是我们通常进行横向复制集添加secondary节点的方法。对于第二种方式,操作繁琐但不用担心oplog被覆盖,且操作期间不会过多担忧网络流量的问题,仅仅考虑网络传输的流量影响。第一种方式操作时间周期长,不可控的影响范围大费时费精力,第二种方式操作时间短,操作的步骤多,容易出现其他问题.
MongoDB secondary节点出现recovering状态 。
MongoDB做了replica sets之后,secondary节点出现recovering状态 。
在一次mongo集群挂掉后,重启,发现有一台服务器的mongo节点一直处于recovering状态,不能变为secondary或者primary.
查询官方文档后,找到解决方案,在此记录.
出现原因 。
备份节点的工作原理过程可以大致描述为,备份节点定期轮询主节点上的数据操作,然后对自己的数据副本进行这些操作,从而保证跟主节点的数据同步.
至于主节点上的所有数据库状态改变的操作,都会存放在一张特定的系统表中。备份节点则是根据这些数据进行自己的数据更新.
上面提到的数据库状态改变的操作,称为oplog(operation log,主节点操作记录)。oplog存储在local数据库的"oplog.rs"表中。副本集中备份节点异步的从主节点同步oplog,然后重新执行它记录的操作,以此达到了数据同步的作用.
关于oplog有几个注意的地方:
数据同步 。
在副本集中,有两种数据同步方式:
initial sync 。
当遇到上面例子中无法同步的问题时,只能使用以下两种方式进行initial sync了 。
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:http://www.cnblogs.com/liyingxiao/p/9768003.html 。
最后此篇关于MongoDB添加secondary节点的2种方法详解的文章就讲到这里了,如果你想了解更多关于MongoDB添加secondary节点的2种方法详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在使用 JavaFX 8 创建一个应用程序。我使用拖/放动态更改网格 Pane 的内容。我希望每行或每行/列迭代 GridPane 内容。JavaFX 允许通过指定行和列在 GridPane 中添
我正在尝试将图像拖放到div上。图像没有被拖到div上并给出以下错误 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': pa
我正在 android studio 中创建内部构建 AR 导航。我正在寻找一种方法将 anchor 与其他 anchor 或 anchor 节点/节点“连接”起来。我不确定使用哪一个。基于我将强制用
我在 Hive 上运行一些作业:首先是 4 节点,然后是 2 节点。令我惊讶的是,我的 2 节点性能比我的 4 节点更好。 首先,我在一个 4 节点(4 个事件节点)上运行查询,然后关闭 2 个节点(
我有 Node* current ,我在其中存储指向列表“顶部”当前节点的指针。当我将一个新节点设置为当前节点时,出现错误: '=' : cannot convert from 'CircularDo
我是 dcos Mesos 的新手,在本地 Ubuntu 机器上安装了 dc os。 我可以查看 dcos 仪表板。 但我无法使用 dcos node ssh --master-proxy --lea
在 JavaFX 中,是否有类似 setLayout(); 的东西?或 setBounds(); ? 例如,我想将按钮定位到我想要的位置。 最佳答案 JavaFX 场景图上的所有内容都是 Node .
我正在开发一个 JavaFX 应用程序,其中我开发的类(从 javafx.scene.Parent 扩展)是根据用户在 ListView 控件中单击的条目动态创建的。 只是要清楚这个节点,它不是使用像
我正在尝试为节点-边缘关系创建一个类图,因为它可以在有向图中找到。我想传达的是,Nodes 引用了 Edges,Edges 也引用了 Nodes。每个 Edge 都恰好需要两个 Node(源和目标)。
在mapreduce作业期间,单个任务将在随机节点上运行,是否有任何方法限制应在其中运行任务的节点? 最佳答案 Hadoop不会选择节点来随机运行任务。考虑到数据局部性,否则将有很多网络开销。 任务与
有什么区别: a) nodetool 重建 b) nodetool 修复 [-pr] 换句话来说,各个命令到底是做什么的? 最佳答案 nodetool重建:类似于引导过程(当您向集群添加新节点时),但
我已将第一个 OneToMany 关系添加到我的 hibernate 3.6.10 项目中。这是一个类: /** * */ package com.heavyweightsoftware.leal
是否有可能找到正在监听触发当前函数的事件的元素? 在下面的代码中,event.target 返回 #xScrollPane 和 event.currentTarget 和 event 的最低子节点.f
我正在尝试覆盖我数据库中的一些数据。结构很简单,就是: recipes { user_1{ recipe_1{data} recipe_2{data} } user_2{
我使用 setInterval 来运行该函数,但它会多次执行函数 2... 如何在输入中插入一个值后执行函数 第一个输入与其余输入的距离不同 如何在插入 val(tab 选项)后将插入从 1 个输入移
我不知道代码有什么问题,但在 visual studio 中不断收到这些错误消息。 Error 18 error C1903: unable to recover from previous e
我正在尝试从其类中获取 SharePoint 搜索导航节点的对象。 var nodes = $("div.ms-qSuggest-listItem"); 我正在获取节点对象,现在想要获取“_promp
D:\nodeP>node main.js module.js:327 抛出错误; ^ 错误:在 Function.Module 的 Function.Module._resolveFilename
struct node{ int key, prior, cnt, val; node *l, *r; node(){} node(int nkey) : key(nkey),
我有以下代码使用迭代器将项目插入双链表。这就是我们被要求这样做的方式。代码有效,但问题是我有 24 字节的绝对内存泄漏。 NodeIterator insert(NodeIterator & itrP
我是一名优秀的程序员,十分优秀!