您的位置:首页 > 数据库 > Mongodb

关于mongodb的journal日志工作方式分析

2013-04-16 17:35 453 查看
1、journal目录结构
[root@gog /backup/mongo/data/journal]#ll
total 3148816
-rw------- 1 root root 1073741824 May 23 19:54 j._2
-rw------- 1 root root         88 May 23 19:54 lsn
-rw------- 1 root root 1073741824 Mar 18 01:22 prealloc.1
-rw------- 1 root root 1073741824 Mar 18 01:22 prealloc.2


j._2表示正在使用中的journal文件,当单个文件达到1GB的时候,就会创建一个新的文件,旧文件不会循环使用,自动删除。lsn保存最后使用的journal序列号,是个2进制文件,它实际保存的是系统启动到现在的一个时间戳。prealloc.2是还未使用的初始化的journal文件。使用db.shutdownServer()和kill -2关闭的系统,也就是clean shutdown,journal文件夹下除prealloc.*文件 都会被删除。 如果系统掉电或者运行时死机,再启动时,mongo就会使用journal进行恢复,不用运行repair。

2、journal刷新频率
journal除了故障恢复的作用之外,还可以提高写入的性能,批量提交(batch-commit),journal一般默认100ms刷新一次,在这个过程中,所有的写入都可以一次提交,是单事务的,全部成功或者全部失败。
关于刷新时间,它是可以更改,范围是2-300ms,但是这并不是绝对的。mongodb提供了journal延迟测试的函数,

> db.runCommand("journalLatencyTest")
{
"timeMillis" : {
"8KB" : 19.74,
"8KBWithPauses" : 20.31402,
"1MB" : 25.2
},
"timeMillisWithPrealloc" : {
"8KB" : 4.13,
"8KBWithPauses" : 4.51596,
"1MB" : 11.4
},
"onSamePartition" : true,
"ok" : 1
}

在实际运行中,刷新时间是--journalCommitInterval设置和延迟测试中较大的一个。
三、总结:
mongodb在启动时,专门初始化一个线程不断循环(除非应用crash掉),用于在一定时间周期内来从defer队列中获取要持久化的数据并写入到磁盘的journal(日志)和mongofile(数据)处,当然因为它不是在用户添加记录时就写到磁盘上,所以它不会造成性能上的损耗,当进行数据插入操作时,记录(Record类型)都被放入到defer队列中以供延时批量(groupcommit)提交写入,但相信其中时间周期参数是个要认真考量的参数,系统为100毫秒,如果该值更低的话,可能会造成频繁磁盘操作,过高又会造成系统宕机时数据丢失过多。
journal的刷新时间是可以改变的,2-300ms的范围,使用 --journalCommitInterval 命令

查看journal运行情况:

"dur" : {
"commits" : 25,
"journaledMB" : 3.899392,
"writeToDataFilesMB" : 38.269053,
"compression" : 0.09879529488786379,
"commitsInWriteLock" : 0,
"earlyCommits" : 0,
"timeMs" : {
"dt" : 3131,
"prepLogBuffer" : 47,
"writeToJournal" : 349,
"writeToDataFiles" : 43,
"remapPrivateView" : 3
}
}

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的时间,越小性能越好

借鉴了/article/4598274.html这篇文章中对mongodb源码的分析部分
官方文档 http://docs.mongodb.org/manual/core/journaling/#journaling-internals本文出自 “明日香” 博客,请务必保留此出处http://leezqang.blog.51cto.com/1525874/1179383
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: