mongoDB 持久化

默认是持久化的

在1.8版本之后开始支持journal,就是我们常说的redo log,用于故障恢复和持久化

在2.0之后的版本,journal都是默认打开的,以确保数据安全

图解:

写入操作会记录journal日志,记录写入操作具体更改的磁盘地址和字节(如果服务器突然崩溃,启动时,journal会重放崩溃前并没有刷新到磁盘上的写操作)

数据文件每隔60s刷新到磁盘上,journal只需要持有60s内的写入数据。journal预分配了几个空文件用于此目的,位于/data/db/journal,命名为_j.0,_j.1等。

MongoDB运行很长时间情况下,在journal目录下,你会看到类似于_j.6217,_j.6218和_j.6219文件。这些文件是当前的journal文件,如果MongoDB一直运行,这些数字会持续增加。当正常关闭MongoDB时,这些文件将被清除,因为正常关机不在需要这些日志。

如果服务器崩溃或kill -9, mongodb再次启动时,会重放journal文件,会输出冗长难懂的检验行,这表明在正常的恢复。

mongod.lock文件,当运行在禁用journal情况下,它是很重要的。

当正常关闭mongod时,会清除mongod.lock文件,下次启动时知道上次是完全关闭的。相反,如果lock文件没有被清除,mongod没有正常的关闭。

如果mongod检测到没有正常的关闭,需要你复制一份数据。然而,有些人已经意识到,可以通过删除这个lock文件来绕过这个检查。但是,不要这么干。在启动时删除lock文件意味着你不知道或不关心你的数据是否已经损坏。除非是这种情况下,请尊重lock文件。

内存中的写入命令达到一定的时间或空间后,写入到日志系统中的日志文件里, 然后日志文件中的内容达到一定时间后,同步到数据文件中,从而保证数据的持久性

从内存同步到硬盘,如果保证强持久化,会导致写入能力下降;如果不设置强持久化,会导致丢失数据的可能; 只能两者之间平衡操作,将写入命令同步到日志的时间间隔尽量缩小 

实现更持久的方法:

1.通过 getLastError 传递 j 选项,日记在记录只会等待30毫秒,而不是默认的100毫秒

db.one.insert({title:'123',content:'456'})
db.runCommand({"getLastError":1,'j':true})

日志写操作是异步的,默认不会等数据写完后才返回,返回给客户端成功但其写并不一定成功,可以通过使用getLastError命令来保证写是成功的

注:如果使用了getLastError中的 j 选项为true,在实际上每秒被限制写入33次。(1次/30毫秒)* (1000毫秒/秒) = 33.3次/秒。 如果允许mongodb对大部分数据进行批量写入,而不是每次写入单独提交,则mongodb性能会更好。 

所以有了优化

提交一次写入操作,会提交这之前的所有操作

即:对应50个写入操作,前49使用getLastError中”j”=false的普通操作,最后一次使用getLastError中j=true的操作,如果成功的话,就知道50次写入已安全的写入到磁盘上了

2.设定日志提交间隔

每隔10毫秒将写入数据写入到日志文件中

  db.adminCommand({"setParameter":1,"journalCommitInterval":10});

journalCommitInterval参数的值范围为 2-500毫秒; 此值越小,丢失数据越少; 

无论时间间隔设置为多少,使用带”j”:true选项的getLastError命令都会将该值减少到原来的1/3 

客户端写入操作被限制的唯一情况:

如果客户端的写入速度超过了日志的刷新速度,mongodb会限制写入操作,知道日记完成磁盘的写入

补充:

系统启动时,会将数据文件映射到一块内存区域,称之为Shared view,在不开启journal的系统中,数据直接写入shared view,然后返回,系统每60s刷新这块内存到磁盘,这样,如果断电或down机,就会丢失很多内存中未持久化的数据。

当系统开启了journal功能,系统会再映射一块内存区域供journal使用,称之为private view,mongodb默认每100ms刷新privateView到journal,也就是说,断电或宕机,有可能丢失这100ms数据,一般都是可以忍受的,如果不能忍受,那就用程序写log吧。这也是为什么开启journal后mongod使用的虚拟内存是之前的两倍。

Mongodb的隔离级别是read_uncommitted,不管使用不使用journal,都是以内存中的数据为准,只不过,不开启journal,数据从shared view读取,开启journal,数据从private view读取。

在开启journal的系统中,写操作从请求到写入磁盘共经历5个步骤,在serverStatus()中已经列出各个步骤消耗的时间。
①、Write to privateView
②、prepLogBuffer
③、WritetoJournal
④、WritetoDataFile
⑤、RemaptoPrivateView

总结:

使用journal之后,备份,容灾得到保障,批量提交也使得写入更加快速。我们也需要选用较高级的文件系统和磁盘还有更多的内存来保障journal的良好运行。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值