mongodb的write concern
mongodb有一个write concern的设置,作用是保障write operation的可靠性。一般是在client driver里设置的,和db.getLastError()方法关系很大
一般来说,所有的mongo driver,在执行一个写操作(insert、update、delete)之后,都会立刻调用db.getLastError()方法。这样才有机会知道刚才的写操作是否成功,如果捕获到错误,就可以进行相应的处理。处理逻辑也是完全由client决定的,比如写入日志、抛出错误、等待一段时间再次尝试写入等。作为mongodb server并不关心,server只负责通知client发生了错误
这里有2点需要注意:
1、db.getLastError()方法是由driver负责调用的,所以业务代码不需要去显式调用。这点后面还会专门提到
2、driver一定会调用db.getLastError()函数,但是并不一定能捕获到错误。这主要取决于write concern的设置级别,这也是本文的主题
write concern:0(Unacknowledged)
此级别调用的时序图如下:
driver调用了getLastError()之后,mongod立刻返回结果,然后才实际进行写操作。所以getLastError()的返回值一定是null,即使之后的Apply发生了错误,driver也不知道。使用这个级别的write concern,driver的写入调用立刻返回,所以性能是最好的,但是可靠性是最差的,因此并不推荐使用。在各平台最新版本的driver中,也不再以0作为默认级别。其实还有一个w:-1的级别,是error ignored,基本上和w:0差不多。区别在于,w:-1不会捕获任何错误,而w:0可以捕获network error
write concern:1(acknowledged)
此级别调用的时序图如下:
和Unacknowledged的区别是,现在mongod只有在Apply(实际写入操作)完成之后,才会返回getLastError()的响应。所以如果写入时发生错误,driver就能捕获到,并进行处理。这个级别的write concern具备基本可靠性,也是目前mongodb的默认设置级别
write concern:1 & journal:true(Jounaled)
此级别调用的时序图如下:
Acknowledged级别的write concern也不是绝对可靠的。因为mongodb的Apply操作,是将数据写入内存,定期通过fsync写入硬盘。如果在Apply之后,fsync之前mongod挂了,或者甚至server挂了,那持久化实际上是失败的。但是在w:1的级别下,driver无法捕获到这种情况下的error(因为response在apply之后就已经返回到driver)
mongod解决这个问题的办法是使用Journal机制,写操作在写入内存之后,还会写到journal文件中,这样如果mongod非正常down掉,重启以后就可以根据journal文件中的内容,来还原写操作。在64位的mongod下,journal默认是打开的。但是32位的版本,需要用--journal参数来启动
在driver层面,则是除了设置w:1之外,再设置journal:true或j:true,来捕获这个情况下的error
write concern:2(Replica Acknowledged)
这个级别只在replica set的部署模式下生效
这个级别下,只有secondary从primary完成了复制之后,getLastError()的结果才会返回。也可以同时设置journal:true或j:true,则还要等journal写入也成功后才会返回。但是注意,只要primary的journal写入就会返回,而不需要等待secondary的journal也写入。类似的也可以设置w:3,表示至少要有3个节点有数据;或者w:majority,表示>1/2的节点有数据。一般小规模的集群就是3节点部署,所以配置w:2就可以了
建议
设置write concern级别,其实就是在写操作的性能和可靠性之间做权衡。写操作的等待时间越长,可靠性就越好。对于非关键数据,建议使用默认的w:1就可以了,对于关键数据,则使用w:1 & j:true比较好。这里要注意,journal无论如何都是建议打开的,设置j:true,只是说driver调用getLastError()之后是否要等待journal写入完成再返回。并不是说不设置j:true就关闭了server端的journal
关于getLastError()
一般来说,开发者写的代码,不需要自行调用db.getLastError()函数,driver在每一个写操作之后,都会立刻自动调用该方法
db.collection("test", {}, function (err, collection) {
collection.insert({name: "world peace"}, function (err, result) {
assert.equal(null, err);
console.log(result);
db.close();
})
});
这段代码,driver在insert()之后,隐式调用db.getLastError(),如果捕获到任何错误,就会赋给回调函数中的err参数。区别就在于是否能够捕获到错误。在w:-1时,err永远是null(没有机会捕获到error);在w:0时,一般也捕获不到,除了network error;在w:1时,如果mongod apply发生错误,就会传递给err参数了。代码都是一样的,区别就在于设置的write concern级别
mongodb的write concern的更多相关文章
- Raft与MongoDB复制集协议比较
在一文搞懂raft算法一文中,从raft论文出发,详细介绍了raft的工作流程以及对特殊情况的处理.但算法.协议这种偏抽象的东西,仅仅看论文还是比较难以掌握的,需要看看在工业界的具体实现.本文关注Mo ...
- mongodb3.2系统性学习——2、write concern mongodb 写安全机制
为了尊重作者原文章位置:http://kyfxbl.iteye.com/blog/1952941 首先讲一下mongodb 的写操作过程: mongodb有一个write concern的设置,作用是 ...
- MongoDB之 写安全(Write Concern)
MongoDB Write Concern,简称MongoDB写入安全机制,是一种客户端设置,用于控制写入安全的级别.Write Concern 描述了MongoDB写入到mongod单实例,副本集, ...
- mongodb官网文档阅读笔记:write concern
write concern保证了mongodb写操作的级别,不同的write concern设置相应了不同级别的写操作.设置的级别越高.那么写操作的性能的持久化做得越好,可是写性能也就越差. mong ...
- 【翻译】MongoDB指南/CRUD操作(三)
[原文地址]https://docs.mongodb.com/manual/ CRUD操作(三) 主要内容: 原子性和事务(Atomicity and Transactions),读隔离.一致性和新近 ...
- 【翻译】MongoDB指南/CRUD操作(二)
[原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,SQL与MongoDB映射图,读隔离(读关 ...
- 【翻译】MongoDB指南/CRUD操作(一)
[原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(一) 主要内容:CRUD操作简介,插入文档,查询文档. CRUD操作包括创建.读取.更新和删 ...
- MongoDB 存储引擎:WiredTiger和In-Memory
存储引擎(Storage Engine)是MongoDB的核心组件,负责管理数据如何存储在硬盘(Disk)和内存(Memory)上.从MongoDB 3.2 版本开始,MongoDB 支持多数据存储引 ...
- [C#项目开源] MongoDB 可视化管理工具 (2011年10月-至今)
正文 该项目从2011年10月开始开发,知道现在已经有整整5年了.MongoDB也从一开始的大红大紫到现在趋于平淡. MongoCola这个工具在一开始定位的时候只是一个Windows版本的工具,期间 ...
随机推荐
- Mac 安装maven3.3.9
只记录一部分自己出错的内容 maven 3 与 jdk 版本的关系 之前安装的jdk是1.8 安装完maven(包括配置环境变量)之后,输入mvn -version 显示版本错误 ,百度之后发现是ma ...
- oracle特殊字符的ascii值
- 给出2n+1个数,其中有2n个数出现过两次,如何用最简便的方法找出里面只出现了一次的那个数(转载)
有2n+1个数,其中有2n个数出现过两次,找出其中只出现一次的数 例如这样一组数3,3,1,2,4,2,5,5,4,其中只有1出现了1次,其他都是出现了2次,如何找出其中的1? 最简便的方法是使用异或 ...
- javascript获得浏览器工作区域的大小
浏览器的窗口发生变化时会执行window.onresize方法,通过这个方法我们可以获得到浏览器工作区域的大小: window.onresize=function(){ bodyHeight = wi ...
- 如何完全禁用或卸载Windows 10中的OneDrive - 51CTO.COM
OneDrive 是微软的个人云存储平台,提供了对个人用户的文件托管.存储和同步等服务,OneDrive 默认被内置在 Windows 10 操作系统当中,而且当用户使用 微软账户 登录时,OneDr ...
- C#委托基础
转载自 http://woshixy.blog.51cto.com/5637578/1070976 C#委托基础1——委托基础 委托和其委托的方法必须具有相同的签名.签名相同:1.参数类型 ...
- Bootstrap_排版_文字样式
一.段落 段落是排版中另一个重要元素之一.在Bootstrap中为文本设置了一个全局的文本样式(这里所说的文本是指正文文本): 1.全局文本字号为14px(font-size). 2.行高为1.428 ...
- [HttpClient]HttpClient简介
1. 前言 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java应用程序需要直接通过 HTTP 协议来访问网路资源.虽然在 JDK 的 java net包中已 ...
- LeetCode Maximum Product Subarray(枚举)
LeetCode Maximum Product Subarray Description Given a sequence of integers S = {S1, S2, . . . , Sn}, ...
- 查看 yum 安装软件包的路径
yum:列出已安装的安装包 [root@localhost ~]# yum list | grep mysql akonadi-mysql.x86_64 1.9.2-4.el7 base apr-ut ...