MongoDB副本集

参考:https://www.cnblogs.com/littleatp/p/8562842.html
https://www.cnblogs.com/ilifeilong/p/14347008.html

MongoDB副本集

MongoDB副本集是由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点。客户端的所有数据都写入Primary,Secondary从Primary同步写入的数据,以保持副本集内所有成员存储相同的数据集,实现数据的高可用。
在这里插入图片描述

1. 副本集角色

  • 主节点Primary:接受所有的写请求,然后把修改同步到所有Secondary,一个副本集只能有一个Primary节点,当Primary挂掉后,其他的Secondary或者Arbiter节点会重新选举出来一个主节点;
  • 副本节点Secondary
  • 仲裁者Arbiter:不保存数据,不能作为主节点,只进行选主投票,使用Arbiter可以减轻数据存储到硬件需求;

2. 两种架构模式

2.1 PSS

Primary + Secondary + Seconda,该模式下副本集节点数比虚伪奇数,使得选主投票时出现大多数(节点总数N,大多数N/2 + 1)的情况。

在这里插入图片描述

2.2 PSA

Primary + Secondary + Arbiter,偶数个数据节点 + 一个Arbiter节点。
在这里插入图片描述

3. 选举机制

3.1 特殊角色
  • Arbiter:只参与投票,不能被选举为Primary,不从Primary同步数据,当副本集成员数为偶数时,最好加入一个Arbiter节点(轻量级),以提升副本集可用性。
  • Priority0:该节点的选举优先级为0,不会被选举为Primary;
  • Vote0:在MongoDB 3.0中,副本集成员最多为50个,参与Primary选举投票的成员最多有7个,其他成员的vote属性必须设置为0,即不参与投票;
  • Hidden:不能被选为Primary(Priority为0),并且对客户端不可见。因Hidden节点不接受客户端请求,可使用Hidden节点做一些数据备份、离线计算的任务,不会影响副本集的服务;
  • Delayed:该节点必须是Hidden节点,并且其数据落后于Primary节点一段时间。因Delayed节点的数据比Primary落后一段时间,当错误或者无效的数据写入Primary时,可通过Delayed节点的数据来恢复到之前的时间点;
3.2 触发选举的条件
  • 初始化一个副本集时;
  • 从库不能连接到主库(默认超过10s),由从库发起选举;
  • 主库放弃Primary角色;
3.3 选举

在这里插入图片描述

  1. 当副本集的从节点ec1-notificationdb-02发现自己无法与主节点ec1-notificationdb-01取得联系并且该从节点有成为主节点的条件时,从节点ec1-notificationdb-02会向所有能到达的其他从节点ec1-notificationdb-03/04/05发送选举通知,请求选举自己为主节点;
  2. 当从节点ec1-notificationdb-0/04/053收到该请求后,会判断该从节点ec1-notificationdb-02可能并不是一个合适的候选者,例如数据副本落后于自己,并且ec1-notificationdb-03/04/05能够和主节点取得联系,只是从节点ec1-notificationdb-02自己无法到达而已,这种情况下,其他从节点会拒绝该申请节点ec1-notificationdb-02的选举请求;
  3. 如果其他从节点ec1-notificationdb-03/04/05并没有反对的理由,那么这些从节点将会对ec1-notificationdb-02的选举请求进行投票,如果ec1-notificationdb-03/04/05中超过半数同意ec1-notificationdb-02的选举请求,那么ec1-notificationdb-02选举成功并且将自己转化为主节点。如果没有得到超过半数的同意,那么在一段时间以后,从节点ec1-notificationdb-02会重新发起选举请求;
  4. 主节点ec1-notificationdb-01将会一直处于Promary角色,如果它无法和副本集中大部分从节点通信,该主节点会自动降级成为从节点;

4. 数据同步

Primary与Secondary之间通过oplog来同步数据,Primary上的写操作完成后,会向特殊的local.oplog.rs特殊集合写入一条oplog,Secondary不断的从Primary获取新的oplog并应用。因 oplog 的数据会不断增加,local.oplog.rs 被设置成为一个 capped 集合,当容量达到配置上限时,会将最旧的数据删除掉。另外考虑到 oplog 在 Secondary 上可能重复应用,oplog 必须具有**幂等性。
如下 oplog 的格式,包含 ts、h、op、ns、o 等字段。

/*ts:时间戳; h:全局唯一标示; v:oplog版本信息; op:操作类型; ns:操作针对的集合; o:操作内容;
*/
{"ts" : Timestamp(1446011584, 2), "h" : NumberLong("1687359108795812092"),"v" : 2,"op" : "i","ns" : "test.nosql","o" : { "_id" : ObjectId("563062c0b085733f34ab4129"), "name" : "mongodb", "score" : "100" }
}

Secondary 初次同步数据时,会先执行 init sync,从 Primary(或其他数据更新的 Secondary)同步全量数据,然后不断通过执行tailable cursor从 Primary 的 local.oplog.rs 集合里查询最新的 oplog 并应用到自身。

5. 回滚

如果一个主节点在写入一条数据后并没有来得及将该数据同步到从节点,此刻主节点突然宕机,这时从节点发起选举请求,选举出新的主节点,那么新的主节点是没有老的主节点那一条数据的。

在这里插入图片描述
如上图所示,在数据"_id:4,username:user004"还没有来得及写入从节点时,主节点因网络故障无法与所有从节点通信,此时从节点将会发起选举请求,选举出主节点,而原有的主节点网络恢复后会被降级成从节点,最终新的主节点的架构图如下:

在这里插入图片描述

这里需要特别注意,原来的主节点以从节点的身份加入副本集后,用自己最新的数据"_id:4, username:user004"和新的主节点对比,发现新的主节点并没有该条数据,于是再用自己较老的数据"_id:3, username:user003"和新的主节点数据对比,发现新的主节点数据和自己匹配,那么该从节点将会回滚数据至"_id:3, username:user003",该版本以后的数据会被存放至数据目录的rollback里,然后开始同步新的主节点的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309652.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

博客系统知多少:揭秘那些不为人知的学问(一)

点击上方蓝字关注“汪宇杰博客”导语在我们生活的年代,博客并不稀奇,甚至可以说是随处可见。从最早的搜狐、新浪博客,再到每个人都曾记录青春的 QQ 空间,再到现在的 Vlog 与 Plog,似乎拥有一个自己的博客并不是什么难事…

MongoDB 分片

MongoDB 分片 高数据量(消耗内存)和高吞吐量(消耗CPU)的数据库应用会对单机的性能造成较大压力,为了解决这些问题,一般采用两种方法:水平扩展(将数据集分布在多个服务器上&#xff…

How many ways HDU - 1978(记忆化搜索关于求多少种方式模板)

题目: 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m)。游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标有的能量。 2.机器人只能向右或者向下走,并且每走一步消耗一单位…

Sql Server之旅——第七站 复合索引和include索引到底有多大区别?

索引和锁,这两个主题对我们开发工程师来说,非常的重要。。。只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的索引都是单列索引。。。当然数据库不可能只认单列索引,还有我这篇的…

Go中new和make的区别

Go中new和make的区别 变量声明 当我们声明变量时可以使用var关键字,当不指定变量的默认值时,这些变量的默认值就是他们的零值,比如int的默认值为0,string的默认值为"",引用类型的零值为nil。 但是当我们在…

POJ 3159 Candies(差分约束+SPAF)

题意: 给n个小朋友分发糖果,但小朋友们之间有嫉妒心。接下来m行,每行三个数,分别表示小朋友A希望B得到的糖果不能比他多x个。要求你计算在满足所有小朋友的条件的情况下最多需要准备多少颗糖。 题目: During the ki…

掌握了Docker Layer Caching才敢自称精通Dockerfile

长话短说:本次原创将向您展示在Docker中使用Layer Cache以加快镜像构建。“这个话题的初衷在于:应用打包过程是很慢的(下载并安装框架&第三方依赖包、生成assets),这个过程在Docker中也不能避免。About Layer Caching in DockerDocker使…

Go unsafe Pointer

Go unsafe Pointer Go被设计为一种强类型的静态语言,强类型意味着类型一旦确定就无法更改,静态意味着类型检查在运行前就做了。 指针类型转换 为了安全考虑,两个不同类型的指针不能相互转换,例如: package mainfun…

How Many Answers Are Wrong HDU - 3038(带权并查集)

题意: TT写一个数列,现在TT会选择一个区间,然后让FF计算这个区间里面所有数的和,FF准备捉弄一下TT,有时候她会故意计算出来一个错的答案,当然TT也比较聪明,他会发现这个答案跟以前的答案会有冲…

ASP.NET Core on K8s学习之旅(14)Ingress灰度发布

【云原生】| 作者/Edison Zhou这是恰童鞋骚年的第236篇原创文章上一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和使用,然后我还录了一个快速分享小视频介绍了一下蓝绿发布和灰度发布策略的基本概念,本篇介绍一下如何实战使用Nginx Ingress实现…

[汇编语言]实验:应用更灵活的寻址方式来定位内存地址

实验内容: (1)将datasg段中每个单词的头一个字母改成大写字母。 datasg段中的数据为: (2) 将datasg段中每个单词的字母改成大写字母。 datasg段中的数据为: ibm dec dos vax …

Redundant Paths POJ - 3177(tarjan+边双连通分量)

题意: 有n个牧场,要求从一个牧场到另一个牧场,要求至少要有2条独立的路可以走。现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指:没有公共边的路&#xff0c…

Slice的本质

Slice的本质 我们先看下面的代码,看看它的输出是什么: package mainimport "fmt"type Slice []intfunc (A Slice) Append(value int) {A append(A, value) } func main() {mSlice : make(Slice, 10, 20)mSlice.Append(5)fmt.Println(mSlice…

你需要了解操作系统发展历程

本文我们大概回顾计算机操作系统发展历程,这里不会记录关于操作系统的完整历史记录,只是记录那些里程碑事件,看看各位接触计算机时,操作系统发展正处于哪个年代起初没有操作系统,没有编程语言或编译器,甚至…

[汇编语言]实验:更灵活的寻址方式 -应用si和di

实验内容: (1) 用寄存器SI和DI实现将字符串‘welcome to masm!’ 复制到它后面的数据区中。 (2) 用[bx(si或di)idata]的方式,来使程序变得简洁。 (1) 代码如下: assume ds:datasg,cs:code…

http.ListenAndServe()到底做了什么?

参考:https://studygolang.com/articles/25849?frsidebar ​ http://blog.csdn.net/gophers 实现一个最简短的hello world服务器 package mainimport "net/http"func main() {http.HandleFunc("/", func(w http.ResponseWriter, r *http.Reque…

Strongly connected HDU - 4635(tarjan+强连通分量)

题意: 给一个简单有向图,让你加最多的边,使他还是一个简单有向图。 题目: Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the graph is still a …