`

mongodb中journal工作原理

 
阅读更多

先介绍一下Journal:

    journal文件在MongoDB中的作用相当于redo日志文件在oracle中的作用,它可以在即使服务器意外宕机的情况下,将数据库操作进行重演。

    在64位的机器上,2.0以上版本默认是开启了journal的,但是在32位机器上,或者2.0以下的版本中,默认是不开启journal的。所以在我的安装了2.4.3版本的32位机器上,每次启动mongodb都提示“warning: 32-bit servers don't have journaling enabled by default. Please use --journal if you want durability.”,所以我须要在启动mongodb时带上 --journal 参数;而在默认启动journal的机器上如果不想启动journal,则可以带上 --nojournal 参数。

    第一次启动带启用journal的服务前,通常磁盘上是没有journal file的,这时mongodb就会现在磁盘上为journal文件分配磁盘空间,这个过程会花比较长的时间(所以老师的视频演示中,第一次启动服务时花了很长的时间),在这段时间内服务是不可用的。如果想避免这个预分配动作也是可以的,就是从别的mongodb实例中拷贝一个已经预分配的文件,然后放到自己的journal路径中,这个预分配文件是不含数据的,因此是这种操作方式是安全的。另外,我在网上看到有人说如果采用ext4的文件系统,这个预分配的时间就会减小很多(据说ext4在ext3基础上性能的提高,比ext3在ext2基础上性能的提高要高不少),可惜我在尝试做这个实验时,尝试了几次把虚拟机CentOS上的ext3文件系统转为ext4都没有成功,所以最终放弃了这个实验,希望如果有人做了这个实验的话,将过程分享分享。

    默认情况下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大小。


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

启动服务前:
1.PNG

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

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

如果发生了写操作:
4.PNG

Private view变脏以后,根据journalCommitInterval的设置,将在一定时间后将写操作往Journal file中复制,这个过程称为“group commit”:
5.PNG
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上:
6.PNG

默认每隔60秒,MongoDB请求操作系统将Shared view刷新输出到Data file:
7.PNG
数据就被写入到数据文件了。这时MongoDB还会将Journal file中已输出到Data file的写操作删除掉(由于MongoDB在将Journal file中写操作放到Shared view时,是通过了一个前指针和一个后指针来操作的,所以MongoDB知道哪些写操作是被放到Shared view了的,哪些没有)。

最后,MongoDB还会例行地如一开始一样,将Shared view映射到Private view,以保持一致性(也是防止Private view变得太过于脏了)。
8.PNG

参考:
    MongoDB官方文档、
    http://blog.mongodb.org/post/337 ... bs-journaling-works

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics