Journal工作原理

journal文件在MongoDB中的作用相当于redo日志文件在oracle中的作用,它可以在即使服务器意外宕机的情况下,将数据库操作进行重演。
    第一次启动服务前,通常磁盘上是没有journal file的,这时mongodb就会现在磁盘上为journal文件分配磁盘空间,这个过程会花比较长的时间,在这段时间内服务是不可用的。如果想避免这个预分配动作也是可以的,就是从别的mongodb实例中拷贝一个已经预分配的文件,然后放到自己的journal路径中,这个预分配文件是不含数据的,因此是这种操作方式是安全的。
    默认情况下mongodb每100毫秒往journal文件中flush一次数据,不过这是在数据文件和journal文件处于同一磁盘卷上的情况,而如果数据文件和journal文件不在同一磁盘卷上时,默认刷新输出时间是30毫秒。不过这个毫秒值是可以修改的,可修改范围是2~300,值越低,刷新输出频率越高,数据安全度也就越高,但磁盘性能上的开销也更高。
    journal文件是以“j._”开头命名的,且是append only的,如果1个journal文件满了1G大小,mongodb就会新创建一个journal文件来使用,一旦某个journal文件所记载的写操作都被使用过了,mongodb就会把这个journal文件删除。通常在journal文件所在的文件夹下,只会存在2~3个journal文件,除非你使用mongodb每秒都写入大量的数据。而使用 smallfiles 这个运行时选项可以将journal文件大小减至128M大小。lsn文件保存最后使用的journal序列号,是个二进制文件,它实际保存的是系统启动后到现在的一个时间戳。prealloc.x代表还未使用的初始化的journal文件。使用db.shutdownServer()和kill -2关闭的系统,也就是clean shutdown,journal文件夹下除prealloc.*文件 都会被删除。 如果系统掉电或者运行时死机,再启动时,mongo就会使用journal进行恢复,不用运行repair。
Journal的工作原理:
   开启journal的系统中,写操作从请求到写入磁盘共经历5个步骤,在serverStatus()中已经列出各个步骤消耗的时间。

①、Write to privateView

②、prepLogBuffer

③、WritetoJournal

④、WritetoDataFile

⑤、RemaptoPrivateView

1、preplogbuffer:

Private view(PV) 中的数据并不是直接刷新到journal文件,而是通过一个中间内存块(journalbuffer,或者aligned buffer)一部分一部分的刷新到journal,这样可以提高并发。preplogbuffer即是将PV中的数据写入到aligned buffer中的过程。这个过程有两部分,basic write 操作和非 basic write操作(e.g.create file)。一次preplogbuffer是以一个commitJob为一个单位,可能会有很多个commitJob写入到aligned buffer,然后提交。一个commitJob中包含多个basic write 和非basic write 操作,basic write是存在Writeintent结构体中的,Writeintent记录了写操作的地址信息。非basic write 操作存在一个vector中

Aligned buffer 有自己的结构,这也是写入到journalfile中的结构。包含Jheader,JsectHeader lsn,Durop,JSectFooter:

每个JsectHeader之间的Durop是属于一个事务范围,一起提交,一起成功,一起失败,即all-or-nothing.上篇文章中介绍的lsn文件,就是记录这个lsn号。

2、WritetoJournal:

writetoJournal操作是将alignedbuffer刷新到JournalFile的过程。默认100ms刷新一次,由--journalCommitInterval 参数控制。writetoJournal会做一些checksum验证,将alignedbuffer进行压缩,然后将压缩过后的alignedbuffer写入到磁盘中的journal文件中。写入磁盘后将删除已经满的Journal文件,更新lsn号到lsn文件。写操作到这一步就是安全的了,因为数据已经在磁盘上,如果使用getlasterror(j=true),这一步即可返回。

3、WritetoDataFile:

WritetoDataFile是将未压缩的aligned buffer写入到shared view的过程,然后由操作系统刷新到磁盘文件中。WritetoDataFile首先会对aligned buffer进行严格的验证,确保没有改变过,然后解析aligned buffer,通过memcpy函数拷贝到shareview

4、RemaptoprivateView:

RemaptoprivateView会将持久化的数据重新映射到PV,以减小PV的大小,防止它不断扩大,按照源码上说,RemaptoprivateView会两秒钟重新映射一次,大约有1000个view,不是一次全做完,而是一部分一部分的做。由于读操作是读取PV,所以在映射完成之后会有短暂的时间读取磁盘。经过这四步,一个写操作就完成了.

首先在这个原理中,存在着两个file,两个view。两个file是 data file 和 journal file,两个view是 shared view 和 private view。两个file是对磁盘而言的,而两个view是对内存而言的.下面以图解的方式解释:

启动服务前:

启动服务后,MongoDB请求操作系统将Data file映射到Shared view,此时操作系统只管映射这个动作,并不将数据加载到Shared view中,而是由MongoDB在需要时再将数据进行加载到Shared view。

然后,MongoDB再请求操作系统将Shared view映射到Private view,之后MongDB对数据的读写操作都是直接操作的Private view:

如果发生了写操作:

Private view变脏以后,根据journalCommitInterval的设置,将在一定时间后将写操作往Journal file中复制,这个过程称为“group commit”:

Journal file中记录的是原生的操作(raw operation),这些原生的操作可以使MongoDB完成以下操作:
    对文档的插入/更新(document insertion/updates)
    对索引的修改(index modifications)
    对命名空间文件的修改(changes to the namespace files)
这些原生操作告诉了Journal file数据变化发生在Data file的什么位置。至此,MongoDB上发生的写事件可以被认为是安全的了,因为这些写操作已经被记录在了Journal file上,即使服务器掉电了,在下次启动MongoDB时,Journal file上的写操作将会被重演。
接下来,Journal file中记录的写操作会应用在Shared view上:

默认每隔60秒,MongoDB请求操作系统将Shared view刷新输出到Data file:

数据就被写入到数据文件了。这时MongoDB还会将Journal file中已输出到Data file的写操作删除掉(由于MongoDB在将Journal file中写操作放到Shared view时,是通过了一个前指针和一个后指针来操作的,所以MongoDB知道哪些写操作是被放到Shared view了的,哪些没有)。
最后,MongoDB还会例行地如一开始一样,将Shared view映射到Private view,以保持一致性(也是防止Private view变得太过于脏了)。

查看journal运行情况

db.serverStatus()

commits:在journalCommitInterval时间内提交的操作数。

journaledMB:在journalCommitInterval时间内写到journal文件中的数据量 。

writeToDataFilesMB:在journalCommitInterval时间内从journal刷新到磁盘的数据量 。

compression:v>2.0,表示客户端提交写入到journal的数据的压缩比率,注意,写入到journal的数据并不是全部的数据。( journaled_size_of_data / uncompressed_size_of_data ) 。

commitsInWriteLock:在有写锁的情况下提交的数量,这表示写的压力很大。

earlyCommits:表示在journalCommitInterval之前的时间,mongod请求提交的次数。用这个参数确定journalCommitInterval是不是设置的过长。

dur.timeMS.prepLogBuffer:从privateView映射到Logbuffer的时间。

dur.timeMS.writeToJournal:从logbuffer刷新到journalfile 的时间。

dur.timeMS.writeToDataFiles:从journalbuffer映射到MMF,然后从MMF刷新到磁盘的时间,文件系统和磁盘会影响写入性能。

dur.timeMS.remapPrivateView:重新映射数据到PrivateView的时间,越小性能越好。这个之后会介绍,这也是为什么journal会使用更多内存的原因,因为journal会另外使用一个叫PrivateView的内存区域

时间: 2024-11-08 16:32:21

Journal工作原理的相关文章

linux 文件系统的管理 (硬盘) 工作原理

一.系统在初始化时如何识别硬盘 1.系统初始时根据MBR的信息来识别硬盘,其中包括了一些执行文件就来载入系统,这些执行文件就是MBR里前面446bytes里的boot loader 程式,而后面的16X4的空间就是存储分区表信息的位置:如下图 2.在分区表中,主要储存了以下信息:(1)分区号,常见的分区号有以下几种:其它编号可以使用fdisk指令,再执行 l (小写L) 查看 0x5 (or 0xf) 扩展分区 0x82 Linux swap 0x83 Linux 0x8e Linux LVM

Android ListView工作原理完全解析(转自 郭霖老师博客)

原文地址:http://blog.csdn.net/guolin_blog/article/details/44996879 在Android所有常用的原生控件当中,用法最复杂的应该就是ListView了,它专门用于处理那种内容元素很多,手机屏幕无法展示出所有内容的情况.ListView可以使用列表的形式来展示内容,超出屏幕部分的内容只需要通过手指滑动就可以移动到屏幕内了. 另外ListView还有一个非常神奇的功能,我相信大家应该都体验过,即使在ListView中加载非常非常多的数据,比如达到

LVS集群之工作原理

  首先我们要了解LVS的工作机制: LVS里Director本身不响应请求,只是接受转发请求到后方,Realservers才是后台真正响应请求. LVS 工作原理基本类似DNAT,又不完全相像,它是一种四层交换,默认情况下通过用户请求的地址和端口来判断用户的请求,从而转发到后台真正提供服务的主机,而判断这种请求的是通过套接字来实现,所以四层就可以实现. 而且这个转发的过程对用户而言是透明的(简单的讲,就是用户访问DR的IP,而DR转发给RSS,而用户不知道这个过程) LVS的工作模式: 1.D

47 监控系统基础及zabbix介绍、zabbix工作原理及安装配置、zabbix on CentOS7、zabbix配置

02    zabbix工作原理及安装配置 配置环境 node1192.168.1.120CentOS6.7 node2192.168.1.121CentOS6.7 1.安装配置zabbix #安装前准备 [[email protected] ~]#yum -y install mysql-server mysq [[email protected] ~]# mysql mysql> CREATE DATABASE zabbix CHARACTER SET utf8; mysql> GRANT

inode工作原理及软连接与硬链接

 inode工作原理及软连接,硬链接 inode: 在linux文件系统中,不管什么类型的文件,保存在磁盘分区中时,系统都会分配一个编号,叫做索引节点index node,简称inode inode里面存储了文件的很多参数: 文件类型,权限.UID,GID,属主,属组 链接数(指向这个文件名路径名称个数) 该文件的大小和不同的时间戳 指向磁盘上文件的数据指针 .... 在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)

quarze的工作原理

quartz的工作原理 http://lavasoft.blog.51cto.com/62575/181907/ 几种定时任务的比較 http://blog.sina.com.cn/s/blog_6940cab30101a5pv.html

Java虚拟机工作原理详解

原文地址:http://blog.csdn.net/bingduanlbd/article/details/8363734 一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 [java] view plaincopy javac YourClassName.java 此时,你的java代码就被编译成字节码(.class).如果你是在Eclipse IDE或者其他开发工具中,你保存代码

HashMap工作原理、深入理解JVM、正则

HashMap工作原理: http://www.importnew.com/7099.html: http://blog.csdn.net/ghsau/article/details/16843543: http://blog.csdn.net/ghsau/article/details/16890151. 深入理解JVM: http://www.importnew.com/17770.html: http://www.cnblogs.com/dingyingsi/p/3760447.html.

[Java] SSH框架笔记_SSH三大框架的工作原理及流程

Hibernate工作原理及为什么要用? 原理:1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息3.通过config.buildSessionFactory();//创建SessionFactory4.sessionFactory.openSession();//打