MongoDB Write Concern,简称MongoDB写入安全机制,是一种客户端设置,用于控制写入安全的级别。Write Concern 描述了MongoDB写入到mongod单实例,副本集,以及分片集群时何时应答给客户端。默认情况下,mongoDB文档增删改都会一直等待数据库响应(确认写入是否成功),然后才会继续执行。本文讲述了MongoDB 应答机制及相关参数。

一、MongoDB应答机制

MongoDB应答机制就是说对于当前数据库的写入成功与否告知客户端(db.getLastError())。如下:
            mongoDB client发出写入(或更新)请求---->mongoDB Server端写入---->通知客户端已经写入OK
    主要分为2种应答机制
            应答式写入(缺省情形,安全写入,适用于数据强一致性场景)
            非应答式写入(非安全写入,适用于数据弱一致性场景)
    实现方式
            通过Write Concern来实现,客户端驱动调用db.getLastError()方法,错误返回给客户端
            如果捕获到错误,则可以通过客户端定义的逻辑尝试再次写入或记录到特定日志等

二、Write Concern用法

{ w: <value>, j: <boolean>, wtimeout: <number> }

w : 该选项要求确认操作已经传播到指定数量的mongod实例或指定标签的mongod实例
            w可选的的值
                    <number>
                            w:1(应答式写入)
                                    要求确认操作已经传播到指定的单个mongod实例或副本集主实例(缺省为1)
                            w:0(非应答式写入)
                                    不返回任何响应,所以无法知道写入是否成功
                                    但是对于尝试向已关闭的套接字写入或者网络故障会返回异常信息
                            w:>1(用于副本集环境)
                                    该值用于设定写入节点的数目,包括主节点

"majority"(大多数)
                    适用于集群架构,要求写入操作已经传递到绝大多数投票节点以及主节点后进行应答

<tag set>
                    要求写入操作已经传递到指定tag标记副本集中的成员后进行应答

j : 该选项要求确认写操作已经写入journal日志之后应答客户端(需要开启journal功能)
            则在意外重启,宕机等情形下可以通过journal来进行数据恢复
            写入journal操作必须等待直到下次提交日志时完成写入
            为降低延迟,MongoDB可以通过增加commit journal的频率来加快journal写入

wtimeout:
            该选项指定一个时间限制,以防止写操作无限制被阻塞导致无法应答给客户端
            wtimeout的单位为ms,当w值大于1时生效,该参数即仅适用于集群环境
            当某个节点写入时超出指定wtimeout之后,mongod将返回一个错误
            在捕获到超时之前,mongod并不会撤销其他节点已成功完成的写入
            wtimeout值为0时等同于没有配置wtimeout选项,容易导致由于某个节点挂起而无法应答

对于单实例应答的情形,是将数据写入到内存后开始应答,除非j:true,则保证掉电后不会丢失数据

三、几种不用应答模式图示说明

1、非应答式写入图示

MongoDB不对客户端进行应答,驱动会检查套接字,网络错误等。
    mongos> db.version()
    3.2.9
    mongos> db.version()
    3.2.9
    mongos> db
    test
    mongos> db.blogs.insert({ename:"leshami",url:"http://blog.csdn.net/leshami"},{writeConcern:{w:0}})
    WriteResult({ })   //此处应答为空

mongos> db.blogs.find({},{_id:0})
    { "ename" : "leshami", "url" : "http://blog.csdn.net/leshami" }


2、应答式写入图示

应答式写入是默认值
    MongoDB会在收到写入操作并且确认该操作在内存中应用后进行应答,但不会确认数据是否已写入磁盘
    同时允许客户端捕捉网络、重复key等等错误

mongos> db.blogs.insert({ename:"john",url:"http://blog.csdn.net/john"},{writeConcern:{w:1}})
    WriteResult({ "nInserted" : 1 })    //此处应答信息显示为1个文档已插入

mongos> db.blogs.find({},{_id:0})
    { "ename" : "leshami", "url" : "http://blog.csdn.net/leshami" }
    { "ename" : "john", "url" : "http://blog.csdn.net/john" }

3、带journal应答式写入图示

确认写操作已经写入journal日志之后应答客户端,必须允许了日志功能,才能生效。
    写入journal操作必须等待直到下次提交日志时完成写入
    提供通过journal来进行数据恢复


4、副本集应答写入图示

对于使用副本集的场景,缺省情况下仅仅从主(首选)节点进行应答
    建议修改缺省的应答情形为特定数目或者majority来保证数据的可靠
    如下示例,w值为2,超时为5s
            db.products.insert(
               { item: "envelopes", qty : 100, type: "Clasp" },
               { writeConcern: { w: 2, wtimeout: 5000 } }
            )       
    如果不希望每次在增删改时添加writeConcern,可以通过设置settings.getLastErrorDefaults
    如下示例,
            cfg = rs.conf()
            cfg.settings = {}
            cfg.settings.getLastErrorDefaults = { w: "majority", wtimeout: 5000 }
            rs.reconfig(cfg)

四、小结

1、write concern用于控制写入安全的级别,可以分为应答式写入以及非应答式写入 
2、write concern是一个性能和数据强一致性的权衡,应根据业务场景进行设定 
3、对于强一致性场景,建议w>1或者等于majority,以及journal为true,否则w=0 
4、在副本集的情形下,建议通过配置文件来修改w以及设置wtimeout,以避免由于某个节点挂起导致无法应答

转:https://blog.csdn.net/leshami/article/details/52913705

MongoDB之 写安全(Write Concern)的更多相关文章

  1. mongodb3.2系统性学习——2、write concern mongodb 写安全机制

    为了尊重作者原文章位置:http://kyfxbl.iteye.com/blog/1952941 首先讲一下mongodb 的写操作过程: mongodb有一个write concern的设置,作用是 ...

  2. 【翻译】MongoDB指南/CRUD操作(二)

    [原文地址]https://docs.mongodb.com/manual/ MongoDB CRUD操作(二) 主要内容: 更新文档,删除文档,批量写操作,SQL与MongoDB映射图,读隔离(读关 ...

  3. Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作

    2 Mongodb CRUD 操作 Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mong ...

  4. MongoDB 副本集的相关概念【转】

    一.副本集基本概念 副本集(replica set) MongoDB的replica set是一个mongod进程实例簇,数据在这个簇中相互复制,并自动进行故障切换. MongoDB的数据库复制增加了 ...

  5. MongoDB丢数据问题的分析

    坊间有很多传说MongoDB会丢数据.特别是最近有一个InfoQ翻译的Sven的一篇水文(为什么叫做水文?因为里面并没有他自己的原创,只是搜罗了一些网上的博客,炒了些冷饭吃),其中又提到了丢数据的事情 ...

  6. [译]MongoDb生产环境注意事项

    译注: 本文是翻译MongoDB Manuel中的MongoDB Production Notes一节内容.这节内容重点关注生产环境中影响性能和可靠性的各种注意事项,值得正在部署MongoDB的工作者 ...

  7. Mongodb FAQ fundamentals(基础篇)

    Mongodb FAQ(基础篇),是官方文档的翻译.如有翻译不到之处,还请谅解. 1.Mongdb是什么数据库? mongodb是一个面向文档(document)的数据库,既不支持表连接,也不支持事务 ...

  8. MongoDB Notes

    MongoDB 启动一个 mongo 实例 $ docker run --name some-mongo -d daocloud.io/mongo 由于该镜像的 Dockerfile 中包含了 EXP ...

  9. node连接mongoDB篇

    一般介绍: 由于mongodb数据库在javascript脚本环境中支持bson对象(json对象的二进制形式)的存取,因此对于数据的存取的效率是非常高的.在mongodb数据库中,将每一条等待插入的 ...

随机推荐

  1. Java读取键盘输入

    三种方法分别如下: 方法一:从控制台接收一个字符,然后将其打印出来 import java.io.*; public static void main(String [] args) throws I ...

  2. el-container 实践上的布局问题

    当自己利用element-ui上面的例子来实现整体布局的时候, 就是自己分开成单独的vue组件时,发现布局是不对的,效果是这样的: 代码是这样的,代码一模一样,只是拆开了各个组件,如下图: 后来发现是 ...

  3. asp.net mvc 实现简单的实时消息推送

    因为项目需要,需要在网页上实现消息的推送.在百度上搜索了一下,发现实现网页上的消息推送,可以使用asp.net 中的SignalR类库,当然也可以使用H5的WebSocket  Ajax的轮回.当然此 ...

  4. L268 A terrifying look at the consequences of climate change

    Climate change is a devilish problem for humanity: at once urgent and slow-moving, immediate and dis ...

  5. day 51

    一 window对象 window 对象表示一个浏览器窗口. 在客户端 JavaScript 中,Window 对象是全局对象,所有的表达式都在当前的环境中计算.也就是说,要引用当前窗口根本不需要特殊 ...

  6. kbmMW随机数与强密码

    kbmMW随机数生成器 为了使基于kbmMW开发的项目更安全,其又提供了随机数及强密码生成实现类,拿来即用,让人感觉真是站到巨人的肩膀上好干活! 随机数方面,kbmMW分别提供32及64位的随机数生成 ...

  7. 如何给cbv的程序添加装饰器

    引入method_decorator模块 1,直接在类上加装饰器 @method_decorator(test,name=‘dispatch’) class Loginview(view) 2,直接在 ...

  8. ubatu 安装nodejs npm liveserver

    更新ubuntu软件源 sudo apt-get update sudo apt-get install -y python-software-properties software-properti ...

  9. mysqli扩展库的预处理

    预处理的特点:1.效率高,执行速度快 2.安全性高,可以防止sql注入 $mysqli  中的函数 $stmt=$mysqli->prepare($sql);             预备一条s ...

  10. pycharm 利用virtualenv为每个项目配置venv

    1.在某个位置安装一个虚拟环境 2.项目运行是配置virtualenv生成的环境 3.重启terminal 安装依赖: exp => pip install django