mongodb3.2系统性学习——2、write concern mongodb 写安全机制
为了尊重作者原文章位置:http://kyfxbl.iteye.com/blog/1952941
首先讲一下mongodb 的写操作过程:
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的设置级别,这也是本文的主题。
3、写安全机制 实际上就是在 安全性跟性能之间做权衡。
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)
- journal 日志操作用于故障回复跟持久化。
- 64位机器上 Mongodb 2.0 以上版本 默认情况下式开启journal的 journal 文件位于 journal 目录中,只能以追加的方式添加数据,文件名称以j._开头。
- 数据库正常关闭的情况下 数据库服务会清空 journal 目录下所有文件。
- mongodb 会每个100ms (或者30ms)向journal文件中flush 一次数据。
此级别调用的时序图如下:
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
writeConcern 函数主要有以下参数:
w:majority 表示 复制集中大多数的节点有数据就可以。
关于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级别
mongodb3.2系统性学习——2、write concern mongodb 写安全机制的更多相关文章
- mongodb3.2系统性学习——4、find()操作
find 操作语法展示: find()操作实例 : //连接数据库 dbService = connect("localhost:27017"); //选择插入集合 db = db ...
- mongodb3.2系统性学习——5、游标 模糊查询 findAndModify函数
1首先介绍查询结果 返回的过程: 进行查询的时候mongodb 并不是一次哪个返回结果集合的所有文档,而是以多条文档的形式分批返回查询的结果,返回文档到内存中. 好处: 减少了客户端与服务器端的查询负 ...
- mongodb3.2系统性学习——3、update()操作
mongodb 包含众多的原子性操作: 实例: //连接数据库 dbService = connect("localhost:27017"); //选择插入集合 db = dbS ...
- MongoDB学习笔记一:MongoDB的下载和安装
MongoDB学习笔记一:MongoDB的下载和安装 趁着这几天比較空暇,准备学习一下MongoDB数据库.今天就简单的学习了一些MongoDB的下载和安装.并创建了存储MongoDB的数据仓库. 将 ...
- MongoDB学习笔记:Python 操作MongoDB
MongoDB学习笔记:Python 操作MongoDB Pymongo 安装 安装pymongopip install pymongoPyMongo是驱动程序,使python程序能够使用Mong ...
- Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...
- Java虚拟机JVM学习05 类加载器的父委托机制
Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...
- Springboot学习04-默认错误页面加载机制源码分析
Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...
- NDK学习笔记(四):OutputContext机制
首先NDK文档中的Op.h头文件中已经有了相关概念的解释,摘录翻译如下: /*! \fn const OutputContext& Op::outputContext() const; The ...
随机推荐
- 数据库数据导入导出系列之五 C#实现动态生成Word(转)
1. 一个控制台例子,实现动态生成Word. 首先,添加引用:COM->Microsoft Word 11.0 Object Library. 2. 介绍几篇牛人写的关于操作Word的文章 [分 ...
- android系统架构图
android的系统架构和其操作系统一样,采用了分层的架构.从架构图看,android分为四个层,从高层到低层分别是应用程序层.应用程序框架层.系统运行库层和Linux核心层. 1.应用程序 Andr ...
- Android SimpleAdapter源码详解
一直没认真看过android的源码,也不太敢看,稀里糊涂也敲了一年的代码,现在想好好学习了,就把常用的源码都看了一下,小伙伴们来涨姿势吧,有错误的地方,直接指出,我脸厚不怕丢人.来吧. 刚开始学and ...
- Xenomai 的模式切换浅析
在Xenomai的用户空间下,有两种模式:primary mode (主模式) 和 secondary mode(次模式). 在主模式下调用Linux系统调用后程序就会进入次模式,反之,在次模式下调用 ...
- mac jdbc连接mysql
1.下载jdbc驱动: http://dev.mysql.com/downloads/connector/j/ 2.增加jdbc的jar包至项目的libs文件夹并build path 2.改动环境变量 ...
- Linux环境进程间通信
http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html http://bbs.chinaunix.net/forum.ph ...
- [Webpack 2] Optimize React size and performance with Webpack production plugins
You can fine tune several webpack plugins to make your bundle as small as it can be for your specifi ...
- ACE的安装方法
ACE的安装方法 下载ACE --1 ACE的主页以及下载链接 http://www.cs.wustl.edu/~schmidt/ACE.html 安装ACE --1 将ACE-5.5.tar.g ...
- Mac OS X 10.7下找不到~/Library/Application Support的解决方案
28二 最近有台机器升级到了Mac OS X 10.7,Finder的sidebar变了不说,连用户目录下的Library目录也不见了.但是Terminal中是有的,估计是被隐藏了.直接在Finder ...
- 下载好一个android软件之后,怎样自动提示安装?
最近在做毕设,里面牵涉到版本更新,当有新版本时可以下载新版本,下载完成之后提示安装.那么怎么实现下载完成之后提示安装呢? 直接上代码吧: File mFile = new File(Environme ...