mongodb基础整理篇————副本原理篇[外篇]
前言
简单介绍一下副本集的原理篇。
正文
下面是几个基本的原理:
副本之间是如何复制的?
mongodb 实现此功能的方式是保存操作日志,其中包含了主节点执行的每一次操作,这和mysql比较像。
oplog 是存在于主节点local数据库中的一个固定集合。从节点通过查询此集合以获取需要复制的操作。
每个从节点都维护自己的oplog,用来记录它从主节点复制的每一个操作。
这使得每个成员都可以被用作其他成员的同步源。
从节点从同步源获取操作,将其应用到自己的数据集上,然后再写入oplog。
如果一个从节点由于某种原因而停止运行,那么当它重新启动后,就会从oplog中的最后一个操作开始同步。
由于这些操作是先应用到数据上,然后再写入到oplog,因此从节点可能会重复已经应用到其数据上的操作。
mongodb 在设计的时候就考虑到了这种情况:将oplog中的一个操作多次与只执行一次的效果一样的。
oplog中的每个操作都是幂等的。
一般来说主节点每分钟写入1kb的数据,那么oplog也是每分钟1kb数据。
但是如果是删除的话,那就不一样,比如说用户删除10000文档,那么oplog 可能就有10000条记录了,而不是oplog产生一条记录。
这样做是为了保障oplog 执行的幂等。
因为opsize 也是有大小的,不可能无限的进行扩长。
这个opsize 设置非常重要,比如说,如果opsize 设置太小的话,那么就一个问题,从节点来不及同步的话而oplog 被删除的话,那么同步就会中断。
在mongod 进程创建oplog 之前,可以使用oplogSizeMB 选项指定其大小。然后,在第一次启动副本集成员后,只能使用"更改oplog大小" 这个流程来更改oplog的大小的。
初始化同步
一般来说,如果一个副本加入到副本集,他就会检查自身状态,如果没有问题,那么就会进行初始化同步。
首先mongodb 会克隆除local数据库之外的所以数据库。mongod 会扫描源数据中的每个集合,并将所以数据插入目标成员上这些集合的对应副本。
在开始克隆操作之前,目标成员上的任何现有数据都将会被删除。
在克隆过程将会将同步源变得缓慢:某些数据的子集经常被访问,因而这部分数据总是存在内存中。
执行初始化同步会强制将其所有数据分页加载到内存中,从而驱逐那些经常使用的数据。原本是可以通过在ram访问的数据,现在要在磁盘上访问自然就慢了。
然后如果数据库很大的话,那么其实是通过备份数据库中来还原数据库,而不是从初始化中来同步。
如果一个从节点远远落后于同步源当前的操作,那么这个节点就是过时的。
那么这个节点会怎么做呢?这个节点会找一个拥有足够长的oplog的节点进行同步,如果找不到,那么就要重新初始化或者从备份中恢复。
为了避免这种情况,那么oplog 必须覆盖两到三天的正常操作。
客户端使用副本集的一些注意点
客户端我们叫做驱动程序。
驱动程序和mongodb 进行写操作的时候,因为是一个网络传输,那么如果保证网络传输的一个幂等性呢?
一般来说,没有网络问题的情况下,直接成功了,这样是没有问题的。
那么有下面几种情况: 1. 服务短暂不可以 2. 服务长时间不可用 3. 服务命令错误,返回错误码
3 这种情况下肯定不进行重试的了。
1 和 2是我们驱动程序不知道,到底是1还是2呢? 那么怎么样的重试策略是好的呢?
如果出现了服务不可用,那么可能就是在故障转移,这个时候在重新进行选举。
所以驱动程序,采用至多重试一次的策略,就是在服务不可用的情况下,等待一个选举时间(估计的时间),然后进行重试。
当然这里有人会提出疑问,万一第一次成功了,第二次运行这样不就有问题了吗?
这个是不用担心的,mongo 做了幂等的。
在写入时等待复制
这个跟kafka 有点像。
是这样的机制,就是在副本集写入的时候,可以设置一些选项,比如大部分副本集同步到了,才返回成功结果。
db.products.insertOne({
"_id":0,
"item":"envelopes"
},
{
"writeConcern":
{
"w":"majority",
"wtimeout":100
}
})
这个writeConcern中的w设置副本集同步多少个。
w 可以是数字,2表示同步了一个从节点。
这里面还可以自定义规则,没用到过,所以这里就不介绍了。
什么时候用副本集从节点读取
这个问题前面也提及过,因为从节点是存在延迟的,如果不介意延迟的话,那么是可以的。
同样,如果考虑到负载情况,从从节点读取的确可以负债压力。
但是如果有你需要负载30000次每秒的读取,但是你主节点只有10000次。
你采用这种方式的话,那么你可以需要4台机器,3台有选举权,1台没有。
但是如果有一台挂了,那么每台机器负荷就是100%,如果有一台出现了问题,需要重新同步数据,那么负荷就会超过100%。
所以这个时候还是建议分片。
维护相关
单机维护
如果希望维护某个从节点,但是又不希望在主节点上维护,那么可以采用单机维护。
使用 db.serverCmdLineOpts() 查看启动命令:
mydb:SECONDARY> db.serverCmdLineOpts()
{
"argv" : [
"mongod",
"--replSet",
"mydb",
"--dbpath",
"/root/data/rs2",
"--logpath",
"/root/logs/rs2/log",
"--port",
"27018",
"--smallfiles",
"--oplogSize=200"
],
"parsed" : {
"net" : {
"port" : 27018
},
"replication" : {
"oplogSizeMB" : 200,
"replSet" : "mydb"
},
"storage" : {
"dbPath" : "/root/data/rs2",
"mmapv1" : {
"smallFiles" : true
}
},
"systemLog" : {
"destination" : "file",
"path" : "/root/logs/rs2/log"
}
},
"ok" : 1,
"operationTime" : Timestamp(1665935221, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1665935221, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
然后将该服务停止。
db.shutdownServer();
然后再换另外一个端口启动:
mongod --port 30000 -dbpath /root/data/rs2
这个就相当于这个从节点脱机维护了。
控制成员状态
如果希望某个主节点不再为主节点:
rs.stepDown(600)
这样主节点就会变成从节点。
如果希望主节点进行维护,同样维护阶段不希望其他从节点成为新的主节点:
其他节点运行:
rs.freeze(10000)
当维护结束,运行:
rs.freeze(0)
副本是如何选择从哪里复制的呢?
一般情况下由系统自动选择。
那么是否可以手动,也是可以的:
secondary.adminCommand({"replSetSyncFrom":"localhost:27018"})
这样就可以设置。
还有一点比较重要的是,要设置这个oplog大小。
这个是很关键的,如果oplog不够,那么很有可能复制就会中断了。
查看当前oplog 大小。
那么需要我们设置一下。
db.adminCommand({"replSetResizeOplog":1,size:16000})
这个就是16G了。
结
下一节分片。
mongodb基础整理篇————副本原理篇[外篇]的更多相关文章
- mongodb基础整理篇————简单介绍[一]
前言 简单介绍一下文档数据库. 正文 mongodb 是一个以json为数据模型的文档数据库. 这里要介绍一下什么是json.因为有些人认为'{a:1,b:2}' 是json,而"this ...
- mongodb基础整理篇————副本概念篇[外篇]
前言 副本集整理. 开始逐步把mongodb博客补齐了. 正文 什么是副本集 副本集是一组服务器,其中一个是用于处理写入操作的主节点,还有多个用于保存主节点的数据副本的从节点. 如果主节点崩溃了,则从 ...
- mongodb基础整理篇————常规操作[二]
前言 简单整理一下常规操作. 正文 虽然一般说写代码看的是思想,但是呢,如果不知道mongodb 有哪些常用的操作,那么你怎么能知道mongodb是否符合你的需求,比如说如果聚合功能都没有,你得自己写 ...
- 重新整理 .net core 实践篇 ———— dotnet-dump [外篇]
前言 本文的上一篇为: https://www.cnblogs.com/aoximin/p/16861797.html 该文为dotnet-dump 和 procdump 的实战介绍一下. 正文 现在 ...
- 【笨木头Lua专栏】基础补充05:迭代器番外篇
关于迭代器的内容, 另一点点,只是已经无关紧要了.应该算是一种扩展吧.就一起来开开眼界好了~ 笨木头花心贡献.哈?花心?不.是用心~ 转载请注明,原文地址: http://www.benmutou.c ...
- 羽夏看Win系统内核—— x64 番外篇
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- VT 入门番外篇——初识 VT
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- 羽夏看Win系统内核—— VT 入门番外篇
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- python自动化测试应用-番外篇--接口测试2
篇2 book-python-auto-test-番外篇--接口测试2 --lamecho辣么丑 大家好! 我是lamecho(辣么丑),今天将继续上一篇python接 ...
- (八)羽夏看C语言——C番外篇
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...
随机推荐
- 彩虹猫IDA分析记录
目录 彩虹猫分析 概述 无参启动 带/main参数启动 带/watchdog参数启动 MBR引导程序和动画程序 第一段 引导代码 第二段 动画代码 其他函数 扭曲桌面 扰乱鼠标 钩子函数 桌面绘制图标 ...
- Jmeter Jsonpath 语法你了解多少?
- 一: Mysql字符集问题
## Mysql 字符集问题 1 修改MySQL5.7字符集 1.1 修改步骤 在MySQL 8.0版本之前,默认字符集为 latin1 ,utf8字符集指向的是 utf8mb3 .网站开发人员在数据 ...
- Java //100以内的质数的输出(从2开始,到这个数-1结束为止,都不能被这个数本身整除)+优化
1 //100以内的质数的输出(从2开始,到这个数-1结束为止,都不能被这个数本身整除) 2 boolean isFlag = true; //标识i是否被j除尽,修改其值 3 4 for(int i ...
- Python列表字典推导式
[一]语法 列表推导式可以利用列表,元组,字典,集合等数据类型,快速的生成一个特定需要的列表. 语法格式如下 [表达式 for 迭代变量 in 可迭代对象 [if 条件表达式]] [二]列表推导式 [ ...
- 单词本z develop vel = 到上面 从下面到上面的一种过程 抽象是相对从无到有
单词本z develop vel = 到上面 从下面到上面的一种过程 抽象是相对从无到有 develop 发展 开发 de = down 下面 velop 这里 vel 就是 lev的反写 op = ...
- 泰凌微TLSR8258芯片解决方案开发之串口打印级别设置
一 TRSR8258简介 该芯片是泰凌微推出来的一款纯ble的芯片,接口丰富,功耗低,资源丰富,非常适合做可穿戴物联网设备,笔者拿这颗芯片做了不少方案,感觉非常好用,所以这里写一下使用心得. 二 串 ...
- 修改Tomcat服务器Server Locations
首先双击我们集成好的Tomcat服务器 修改Server Locations选项 Specify the server path (i.e. catalina.base) and deploy p ...
- display标签交替显示不同行颜色
问题 想要一个更加简单的支持列表数据分页和排序的方法. 解决方案 使用Display标签库和JSP标签库. 例4.13介绍了一个JSP页,它使用4.5节中的数据模型显示美国总统列表.这个JSP页面使用 ...
- 反编译和逆向出现:java.lang.VerifyError(新问题样本)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...