第39章:MongoDB-集群--Replica Sets(副本集)---副本集基本原理
Oplog是主节点的local数据库中的一个固定集合,按顺序记录了主节点的每一次写操作,MongoDB的复制功能是使用oplog来实现的,备份节点通过查询这个集合就可以知道需要进行哪些数据的复制了。
每个备份节点也都维护着自己的oplog,记录着每次从主节点复制数据的操作。这样每个节点都可以作为数据的同步源提供给其他成员使用。
注意几点:
1:由于是先复制数据,再写日志,因此可能会出现重复的复制操作,这个没有关系,MongoDB会处理这种情况,多次执行Oplog中同一个操作与执行一次是一样的。
2:oplog的大小是固定的,它只能保存特定数量的操作日志,如果多次大批量的执行操作,oplog很快就会被填满,oplog的大小,可以通过mongod的--plogSize来指定
3:oplog的内容,在local数据库的oplog.rs集合里面 db.oplog.rs.find();
当副本集中的一个成员启动的时候,它就会检查自身状态,然后到集群中检查是否需要同步,以及从哪儿同步,并进行数据的复制,这个过程就称为初始化同步。
大致步骤如下:
1:记录前的准备工作:选择一个成员作为同步源,在local.me中为自己创建一个标识符,删除所有已存在的数据库,以全新的状态开始同步
2:从数据源把所有数据复制到本地
3:写oplog,把所有复制中的操作写入oplog
4:把上一步oplog同步中的操作记录下来
5:此时数据应该和数据源一致了,可以开始创建索引了
6:如果当前节点的数据仍然远远落后于数据源,那么oplog会将创建索引期间的所有操作同步过来
7:完成初始化同步后,切换到普通同步状态,也就可以作为备份节点使用了
如果备份节点远远落后于同步源的数据,那么这个节点上的数据就是成旧数据。
通常的处理办法是:让主节点使用比较大的oplog,以保存足够多的操作日志,可以让备份节点慢慢来同步操作。
为了维护集合的最新状态,每个成员每隔2秒会向其他成员发送一个心跳请求,用于检查每个成员的状态。
常见状态如下:
1:主节点、备份节点
2:STARTUP:成员刚启动时处于这个状态,加载完副本集配置后,进入STARTUP2
3:STARTUP2:整个初始化同步过程都处于这个状态
4:RECOVERING:表明成员运转正常,但暂时还不能处理读取请求
5:ARBITER:仲裁者始终处于这个状态
系统出问题的话,会处于如下状态
1:DOWN:成员不可到达,有可能成员还是在正常运行,也有可能挂了
2:UNKNOWN:标识一个成员无法到达其他所有的成员
3:REMOVED:成员被移出副本集
4:ROLLBACK:成员正在进行数据回滚
5:FATAL:成员出现了致命的错误,也不再尝试恢复正常
回滚的时候,会把受到影响的文档,保存到数据目录下的rollback目录中,文件名为集合名.bson,基本步骤是:
1:判断是否需要回滚,典型就是副本记录和主记录不一致了
2:在两个oplog中寻找最后一个共同的点
3:然后副本回滚到这个共同的点
4:副本再从主节点同步数据回来
注意:
如果要回滚的数据很多,比如大于300M,或者需要操作30分钟以上,回滚就会失败。如果回滚失败的话,就需要重新同步了。
在 MongoDB 副本集中,主节点负责处理客户端的读写请求,备份节点则负责映射主节点的 数据。备份节点的工作原理过程可以大致描述为,备份节点定期轮询主节点上的数据操作,然后对 自己的数据副本进行这些操作,从而保证跟主节点的数据同步。至于主节点上的所有 数据库状态改变 的操作,都会存放在一张特定的系统表中。备份节点则是根据这些数据进行自己的数据更新。
oplog
上面提到的数据库状态改变的操作,称为 oplog(operation log,主节点操作记录)。oplog 存储在 local 数据库的"oplog.rs"表中。副本集中备份节点异步的从主节点同步 oplog,然后重新 执行它记录的操作,以此达到了数据同步的作用。
关于 oplog 有几个注意的地方:
1)oplog 只记录改变数据库状态的操作
2)存储在 oplog 中的操作并不是和主节点执行的操作完全一样,例如"$inc"操作就会转化为"$set"操作
3)oplog 存储在固定集合中(capped collection),当 oplog 的数量超过 oplogSize,新的操作就会覆盖就的操作
数据同步
在副本集中,有两种数据同步方式:
1)initial sync(初始化):这个过程发生在当副本集中创建一个新的数据库或其中某个节点刚从宕机中恢复,或者向副本集中添加新的成员的时候,默认的,副本集中的节点会从离 它最近的节点复制 oplog 来同步数据,这个最近的节点可以是 primary 也可以是拥有最新 oplog 副本的 secondary 节点。该操作一般会重新初始化备份节点,开销较大。
2)replication(复制):在初始化后这个操作会一直持续的进行着,以保持各个 secondary 节点之间的数据同步。
initial sync
当遇到无法同步的问题时,只能使用以下两种方式进行 initial sync 了
1)第一种方式就是停止该节点,然后删除目录中的文件,重新启动该节点。这样,这个节 点就会执行 initial sync注意:通过这种方式,sync 的时间是根据数据量大小的,如果数据量过大,sync 时间就会很长同时会有很多网络传输,可能会影响其他节点的工作
2)第二种方式,停止该节点,然后删除目录中的文件,找一个比较新的节点,然后把该节点目 录中的文件拷贝到要 sync 的节点目录中
通过上面两种方式中的一种,都可以重新恢复"port=33333"的节点。不在进行截图了。
副本集管理
1)查看oplog的信息 通过"db.printReplicationInfo()"命令可以查看 oplog 的信息
字段说明:
configured oplog size: oplog 文件大小
log length start to end: oplog 日志的启用时间段
oplog first event time: 第一个事务日志的产生时间
oplog last event time: 最后一个事务日志的产生时间
now: 现在的时间
2)查看 slave 状态 通过"db.printSlaveReplicationInfo()"可以查看 slave 的同步状态当插入一条新的数据,然后重新检查 slave 状态时,就会发现 sync 时间更新了
Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败,则备份节点停止从当前数据源复制数据。如果某个备份节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB在设计之初就考虑到这个问题,将oplog的同一个操作执行多次,与执行一次的效果是一样的。简单的说就是:
当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步:
1)检查自己local库的oplog.rs集合找出最近的时间戳。
2)检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。
3)将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。
副本集的同步和主从同步一样,都是异步同步的过程,不同的是副本集有个自动故障转移的功能。其原理是:slave端从primary端获取日志,然后在自己身上完全顺序的执行日志所记录的各种操作(该日志是不记录查询操作的),这个日志就是local数据 库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小可以在启动参数中设 定:--oplogSize 1000,单位是M。
注意:在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。
Mongodb副本集选举采用的是Bully算法,这是一种协调者(主节点)竞选算法,主要思想是集群的每个成员都可以声明它是主节点并通知其他节点。别的节点可以选择接受这个声称或是拒绝并进入主节点竞争,被其他所有节点接受的节点才能成为主节点。节点按照一些属性来判断谁应该胜出,这个属性可以是一个静态 ID,也可以是更新的度量像最近一次事务ID(最新的节点会胜出)
副本集的选举过程大致如下:
1)得到每个服务器节点的最后操作时间戳。每个 mongodb 都有 oplog 机制会记录本机的操作,方便和主服 务器进行对比数据是否同步还可以用于错误恢复。
2)如果集群中大部分服务器 down 机了,保留活着的节点都为 secondary 状态并停止,不选举了。
3)如果集群中选举出来的主节点或者所有从节点最后一次同步时间看起来很旧了,停止选举等待人来操作。
4)如果上面都没有问题就选择最后操作时间戳最新(保证数据是最新的)的服务器节点作为主节点。
副本集选举的特点:
选举还有个前提条件,参与选举的节点数量必须大于副本集总节点数量的一半(建议副本集成员为奇数。最多12个副本节点,最多7个节点参与选举)如果已经小于一半了所有节点保持只读状态。集合中的成员一定要有大部分成员(即超过一半数量)是保持正常在线状态,3个成员的副本集,需要至少2个从属节点是正常状态。如果一个从属节点挂掉,那么当主节点down掉 产生故障切换时,由于副本集中只有一个节点是正常的,少于一半,则选举失败。4个成员的副本集,则需要3个成员是正常状态(先关闭一个从属节点,然后再关闭主节点,产生故障切换,此时副本集中只有2个节点正常,则无法成功选举出新主节点)。
当你的用户抱怨修改过的信息不改变,删除掉的数据还在显示,你掐指一算,估计是数据库主从不同步。与其他提供数据同步的数据库一样,MongoDB 也会遇到同步延迟的问题,在MongoDB的Replica Sets模式中,同步延迟也经常是困扰使用者的一个大问题。
什么是同步延迟?
首先,要出现同步延迟,必然是在有数据同步的场合,在 MongoDB 中,有两种数据冗余方式,一种是Master-Slave 模式,一种是Replica Sets模式。这两个模式本质上都是在一个节点上执行写操作, 另外的节点将主节点上的写操作同步到自己这边再进行执行。在MongoDB中,所有写操作都会产生 oplog,oplog 是每修改一条数据都会生成一条,如果你采用一个批量 update 命令更新了 N 多条数据, 那么抱歉,oplog 会有很多条,而不是一条。所以同步延迟就是写操作在主节点上执行完后,从节点还没有把 oplog 拿过来再执行一次。而这个写操作的量越大,主节点与从节点的差别也就越大,同步延迟也就越大了。
同步延迟带来的问题
首先,同步操作通常有两个效果,一是读写分离,将读操作放到从节点上来执行,从而减少主节点的 压力。对于大多数场景来说,读多写少是基本特性,所以这一点是很有用的。另一个作用是数据备份, 同一个写操作除了在主节点执行之外,在从节点上也同样执行,这样我们就有多份同样的数据,一旦 主节点的数据因为各种天灾人祸无法恢复的时候,我们至少还有从节点可以依赖。但是主从延迟问题 可能会对上面两个效果都产生不好的影响。
如果主从延迟过大,主节点上会有很多数据更改没有同步到从节点上。这时候如果主节点故障,就有 两种情况:
1)主节点故障并且无法恢复,如果应用上又无法忍受这部分数据的丢失,我们就得想各种办法将这部 数据更改找回来,再写入到从节点中去。可以想象,即使是有可能,那这也绝对是一件非常恶心的活。
2)主节点能够恢复,但是需要花的时间比较长,这种情况如果应用能忍受,我们可以直接让从节点提 供服务,只是对用户来说,有一段时间的数据丢失了,而如果应用不能接受数据的不一致,那么就只能下线整个业务,等主节点恢复后再提供服务了。
如果你只有一个从节点,当主从延迟过大时,由于主节点只保存最近的一部分 oplog,可能会导致从 节点青黄不接,不得不进行 resync 操作,全量从主节点同步数据。带来的问题是:当从节点全量同步的时候,实际只有主节点保存了完整的数据,这时候如果主节点故障,很可能全 部数据都丢掉了。
第39章:MongoDB-集群--Replica Sets(副本集)---副本集基本原理的更多相关文章
- 第36章:MongoDB-集群--Replica Sets(副本集)
①副本集 副本集是一种在多台机器同步数据的进程,副本集体提供了数据冗余,扩展了数据可用性.在多台服务器保存数据可以避免因为一台服务器导致的数据丢失.也可以从硬件故障或服务中断解脱出来,利用额外的数据副 ...
- 第38章:MongoDB-集群--Replica Sets(副本集)---多机的搭建
①机器环境 182.48.115.236 master-node(主节点) 182.48.115.237 slave-node1(从节点) 182.48.115.238 slave- ...
- 第37章:MongoDB-集群--Replica Sets(副本集)---单机的搭建
①创建副本集 1:先创建几个存放数据的文件夹,比如在前面的dbs下面创建db1,db2,db3: 同理在前面的logs下面创建logs1,logs2,logs3 2:在启动MongoDB服务器的时候, ...
- 第40章:MongoDB-集群--Replica Sets(副本集)---副本集的管理
①以单机模式启动成员 由于很多维护的工作需要写入操作,所以不合适在副本集中操作,可以以单机模式启动成员,也就是不要使用副本的选项,就跟以前启动单独的服务器一样.一般使用一个跟副本集配置中不一样的端口号 ...
- MongoDB 集群搭建(主从复制、副本及)(五)
六:架构管理 mongodb的主从集群分为两种: 1:master-Slave 复制(主从) --从server不会主动变成主server,须要设置才行 2:replica Sets 复制(副本 ...
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
在上一篇文章<搭建高可用mongodb集群(二)—— 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...
- 搭建高可用mongodb集群(三)—— 深入副本集内部机制
在上一篇文章<搭建高可用mongodb集群(二)-- 副本集> 介绍了副本集的配置,这篇文章深入研究一下副本集的内部机制.还是带着副本集的问题来看吧! 副本集故障转移,主节点是如何选举的? ...
- Apache shiro集群实现 (六)分布式集群系统下的高可用session解决方案---Session共享
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
- Apache shiro集群实现 (七)分布式集群系统下---cache共享
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
随机推荐
- sed -i命令详解
[root@www ~]# sed [-nefr] [动作] 选项与参数: -n :使用安静(silent)模式.在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上.但如果加 ...
- solidworks建立三维模型里面的几何对象和工程图里面的元素的联系
本文是帮助里面的一个例子, 首先打开一个三维模型和对应的工程图,保持三维模型为当前激活窗口,在三维模型里面选中一个面或者一个边,然后运行下面的代码, 会将工程图里面的第一视图里面对应的投影元素的线型的 ...
- git本地推送远程
第一次将本地映射到已经存在的仓库 https://techoverflow.net/2017/08/09/how-to-solve-git-fatal-no-configured-push-desti ...
- 关于spfa
关于spfa的一些事宜.... 刚开始学的时候只会跑最短路,代码都是背下来的.以下是背的代码... inline void spfa(int s) { queue<int>q;q.push ...
- MySQL数据库的基础学习
1.什么是数据库 用来存储数据的仓库,简称数据库; 数据库可以在硬盘和内存中存储数据 数据库存储数据的本质: 通过文件来存储数据 2.数据库存储数据与文件存储的区别 (1).一个文件仅仅只能存储在一个 ...
- [Ting's笔记Day6]活用套件carrierwave gem:(1)在Rails实现图片上传功能
carrierwave是一款经典的图片上传套件,本篇的目标是先在本地端(development)的rails项目试成功gem. (预计中集的进度会练习怎么利用Amazone S3架设图片上传Host, ...
- Echarts 饼状图自定义颜色
今天给饼状图着色问题,找了好久 终于找到了 话不多说直接上代码 $.ajax({ url: "/HuanBaoYunTai/ajax/HuanBaoYunTaiService.ashx&qu ...
- 通过windows远程桌面连接CentOS系统
前提: CentOS安装桌面,如果无桌面,请执行 # yum -y groups install "GNOME Desktop" # startx 1 2 配置源 # yum in ...
- Java学习笔记(十四):java常用的包
- Mysql 关键字
ADD ALL ALTER ANALYZE AND AS ASC ASENSITIVE BEFORE BETWEEN BIGINT BINARY BLOB BOTH BY CALL CASCADE C ...