[title]Journal工作原理[/title]

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的内存区域

吾爱博客|AYFRE.COM 版权所有,转载请标明出处
吾爱博客 » Journal工作原理

50 评论

  1. I was very happy to find this web site. I need to to
    thank you for ones time just for this fantastic read!!
    I definitely savored every bit of it and i also have you saved as a favorite to look at new stuff on your web site.

  2. Greetings, I do believe your blog might be having internet browser compatibility issues.
    Whenever I take a look at your site in Safari, it
    looks fine however when opening in I.E., it has some overlapping issues.
    I merely wanted to provide you with a quick heads up!

    Aside from that, wonderful website!

  3. I like the valuable information you provide to your articles.
    I will bookmark your weblog and take a look at once more right here regularly.
    I’m slightly sure I will be told lots of new stuff right right here!
    Best of luck for the next!

  4. When someone writes an piece of writing he/she retains the thought of a user in his/her brain that how
    a user can know it. So that’s why this piece of writing is perfect.
    Thanks!

  5. Superb post however , I was wondering if you could write a litte more
    on this topic? I’d be very grateful if you could elaborate a little bit more.

    Thanks!

  6. magnificent put up, very informative. I ponder why the opposite specialists
    of this sector do not realize this. You should continue your writing.

    I am confident, you’ve a great readers’ base already!

  7. Asking questions are genuinely good thing if you are not understanding anything completely, however this paragraph offers good understanding even.

  8. We are a group of volunteers and opening a new scheme in our community.
    Your site offered us with valuable information to work on. You’ve
    done an impressive job and our entire community will be thankful to you.

  9. magnificent post, very informative. I ponder why the opposite experts of this sector do not realize this.
    You must proceed your writing. I’m confident, you have a great
    readers’ base already!

  10. I absolutely love your blog and find most of your post’s to
    be precisely what I’m looking for. Would you offer guest writers
    to write content available for you? I wouldn’t mind composing a post or elaborating on many of the subjects you write regarding here.
    Again, awesome web log!

发表评论

吾爱博客|AYFRE.COM