Mongodump的archive(归档)模式原理解析

Mongodump是MongoDB官方的逻辑备份工具,本文将介绍其archive(归档)模式的相关原理。

archive模式

使用archive输出的话,mongodump会将各个集合的数据进行一个混合,最后输出到一个文件里。这样有两个好处:

  1. 方便进行网络传输。
  2. 方便和其他工具配合使用如直接作为mongorestore的输入。

Mongodump的archive模式的实现支持多个集合并发进行dump,通常来说要实现并发就很难做到输出到一个文件中,我们来看下它是怎么做的。

流程

Mongodump使用go写的,因此大量使用了goroutine。主要需要关注两类goroutine,一类是dump数据的(可指定并行度即goroutine个数)Backup goroutine,还有一个则是混合各集合数据并真正输出到归档文件的Multiplexer goroutine。如下图所示:

初始

这个Multiplexer goroutine主要通过一个select调用来通过channel接收backup goroutine过来的数据。它被设计成可以动态添加和删除select的channel,初始化时会有一个control channel用于接收需要监听哪些channel。当一个backup goroutine开始准备对某个集合进行备份时,它会创建3个channel:一个用于发送集合数据给Multiplexer goroutine的writeChan、一个用于从Multiplexer goroutine接收写成功数据长度的writeLenChan,还有一个用于从Multiplexer goroutine接收集合dump完毕信号的writeCloseFinishedChan。除了这3个channel之外,它还会创建一个16MB大小的buf。它把这些数据封装在一个MuxIn数据结构里,通过control channel发送给Multiplexer goroutine。

当Multiplexer goroutine启动后就不停的执行select(),当它从control channel收到MuxIn数据结构时,就会将其中的writeChan添加到select的channel中,并将这个MuxIn保存在自己的数组中。然后下一轮循环就会开始监听control channel和这个writeChan。

dump过程

每个Backup goroutine开始干活时,它一边从mongodb dump数据,一边将数据通过writeChan发送给Multiplexer goroutine。这是一个典型的生产者消费者模型,为了不让消费者的磁盘I/O影响到生产者(从mongodb读数据),它又起了一个Dump goroutine,通过一个buffChan来传输数据,顺便在这个goroutine中处理退出信号(主goroutine起了一个信号处理goroutine用于捕获SIGTERM、SIGINT和SIGHUP,再通过一个termChan和其他goroutine通信),当接收到退出信号时,关闭buffChan并退出。

Backup goroutine的buf收满之后,就将数据通过writeChan发送给Multiplexer goroutine,并等待从writeLenChan接收数据,如果返回的写成功的数据长度和buf的数据长度不一致 ,则返回失败。

Multiplexer goroutine从writeChan收到数据,将数据写入归档文件。由于同时可能有多个Backup goroutine在工作,因此需要对数据进行混合。这里主要是按集合进行分条(slice)处理,每个条有一个header、body和一个terminator。Header就是集合的Namespace(db和集合名),body是集合的数据,terminator是一个4字节的结束标记。另外每个集合的最后一条之后还有一个标明集合结束的EOF条。Multiplexer goroutine会维护一个当前正在处理的集合名,如果发生集合数据交叉,会结束当前条(写入一个terminator),然后另起一个新的条(写入一个新的header)。写完数据后,会将这次写成功的数据通过writeLenChan发送给Backup goroutine。归档文件的物理格式如下图所示:

结束

Backup goroutine针对某个集合dump结束时,会依次关闭writeChan、writeLenChan,然后等待从writeCloseFinishedChan接收数据。Multiplexer goroutine感知到writeChan关闭时,发送数据给writeCloseFinishedChan,然后往当前条写入条结束标记以及EOF条。这里之所以要有一个writeCloseFinishedChan是为了避免Multiplexer goroutine的control channel比writeChan先关闭。如果control channel关闭了,那就会结束整个dump过程。Backup goroutine从writeCloseFinishedChan接收到数据返回后又可以处理下一个集合,直到所有集合处理完毕。

Goroutine们何时退出

主goroutine在创建Backup goroutine时会创建一个resultChan。当Backup goroutine发现所有集合都dump完毕时,或者在dump过程中遇到错误时,都会往resultChan发送数据并退出。当主goroutine从resultChan接收到每个Backup goroutine发送的数据时,或者收到某个Backup goroutine发送的错误,就会返回。当主goroutine干完所有事情返回时,它会关闭Multiplexer goroutine的control channel,这样Multiplexer goroutine就可以退出了。

结语

Mongodump通过这种架构实现了输出到一个归档文件兼顾支持并发的需求,可以作为一个参考。

参考文献

  1. Multiplexing Golang Channels to Maximize Throughput
时间: 2024-08-01 15:51:46

Mongodump的archive(归档)模式原理解析的相关文章

Mongorestore的archive(归档)模式恢复原理解析

在上篇Mongodump的archive(归档)模式原理解析中介绍过,Mongodump的archive(归档)模式产生的文件是将多个集合的数据通过一个Multiplexer多路复用混合在一起,因此对应在恢复的时候就需要有一个Demultiplexer来将数据进行解析,是一个多路复用的逆过程.对应于mongodump,MongoDB官方提供了mongorestore这个恢复工具. 归档文件的格式 复习一下归档文件的格式,其最前面有4个字节的magic number,然后是元数据部分(prelud

秋色园QBlog技术原理解析:独创的多语言翻译机制(九)

文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色园QBlog技术原理解析:UrlRewrite之无后缀URL原理(三) --介绍如何实现无后缀URL 4: 秋色园QBlog技术原理解析:UrlRewrite之URL重定向体系(四) --介绍URL如何定位到处理程序 5: 秋色园QBlog技术原理解析:Module之页面基类设计(五) --介绍创建

秋色园QBlog技术原理解析:Web之页面处理-内容填充(八)

文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色园QBlog技术原理解析:UrlRewrite之无后缀URL原理(三) --介绍如何实现无后缀URL 4: 秋色园QBlog技术原理解析:UrlRewrite之URL重定向体系(四) --介绍URL如何定位到处理程序 5: 秋色园QBlog技术原理解析:Module之页面基类设计(五) --介绍创建

归档和非归档模式下ORA-01145错误的解决方法

总结了一下,在归档和非归档的场景下,ora-01145这个错误可能有如下三种情况: 1.off line tablespace --在非归档模式下尝试ofline 数据文件 SQL> alter tablespace tools offline immediate; alter tablespace tools offline immediate * ERROR at line 1:ORA-01145: offline immediate disallowed unless media reco

Oracle的Archive Log模式下的恢复工作

oracle|恢复     学习并测试了一下Oracle数据库在开启Archive Log模式下的恢复. 系统是Win2K Server+Oracle 8.1.7. 参考了Chinaunix.net和ITPub.com网站相关资料.在此感谢给我的帮助. 注意,养成一个好的习惯非常重要.在开始恢复之前,以及恢复完成后,都要做一个系统全备份. 首先,要开启Archive Log归档日志模式 1. 关闭数据库 2. 修改initSID.ora文件.这个文件通常在$ORACLE_HOME/admin/$

如何修改Oracle数据库为非归档模式

操作步骤如下: 步骤 1 以oracle用户登录服务器,执行以下命令进入SQLPLUS. oracle@smgwrpt:~> sqlplus "/as sysdba" 步骤 2 查看数据库当前归档模式. SQL> archive log list Database log mode              Archive Mode Automatic archival             Enabled Archive destination            U

oralce非归档模式下的恢复(一)历史日志没有被覆盖(可完全恢复)

案例1: 历史日志没有被覆盖(可以完全恢复) 1)切换到非归档模式 SQL> archive log list Database log mode              Archive Mode Automatic archival             Enabled Archive destination            /disk1/arch/anny Oldest online log sequence     7 Next log sequence to archive  

windows 7上如何更改oracle 11g的归档模式

在win7上更改oracle 11g的归档模式,描述包括可能遇到的错误,这些错误也是写这篇博文的初衷,就是为了让其它通道避免同样的错误,或者碰到同样的错误指导如何解决,因为命令已经很清楚,所以就不详细解释. SQL> conn sys/oracle@osid as sysdba 已连接. SQL> select instance_name from V$instance; INSTANCE_NAME -------------------------------- osid SQL> a

Oracle RAC环境下如何修改归档模式

RAC环境下的归档模式切换与单实例稍有不同,主要是共享存储所产生的差异.在这种情况下,我们可以将RAC数据库切换到非集群状态下,仅仅在一个实例上来实施归档模式切换即可完成RAC数据库的归档模式转换问题.本文主要描述了由非归档模式切换到归档模式,而由非归档切换的归档步骤相同,不再赘述. 1.主要步骤: 备份spfile,以防止参数修改失败导致数据库无法启动 修改集群参数cluster_database为false 启动单实例到mount状态 将数据库置于归档模式(alter database ar