专栏首页乐沙弥的世界MongoDB 写安全(Write Concern)

MongoDB 写安全(Write Concern)

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,以避免由于某个节点挂起导致无法应答

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Failed to create or upgrade OLR

        对于Oracle 11g RAC 的安装,与Oracle 10g(clusterware)类似,grid 安装完毕后需要执行orainstroot.sh...

    Leshami
  • Percona XtraDB Cluster添加仲裁节点

    Galera Arbitrator是Percona XtraDB集群的成员,用于投票,以防您拥有少量服务器(通常为两个)并且不希望添加更多资源。Galera仲裁...

    Leshami
  • Python语言编译器与解释器

    版权声明:本文为博主原创文章,欢迎扩散,扩散请务必注明出处。

    Leshami
  • 学习前端不存在跟不上进度的情况

    经常有人问我,老师,我想参加先行者计划,但我担心学习跟不上进度,怎么办? 学习跟不上进度,这句在过去只存在于学校老师嘴里的话,现在随着各种学习班、组织、机构的...

    web前端教室
  • 今天中午刚收到的,快手Java开发(书面offer) 烫手!!!

    今天中午刚收到书面offer,距离面试完过去了24天...虽然审批流程如此漫长,但是不得不说快手的面试体验很棒和面试流程效率很高

    Java架构技术
  • 首都机场启用人脸识别安检,通过效率提升66%

    上个月底,首都机场T2航站楼,启用了一条全新的智能安检系统,这个系统由自动传输、信息、人脸识别、自助验证等模块组成。

    量子位
  • PHP数据结构(八) ——赫夫曼树实现字符串编解码(理论)

    PHP数据结构(八)——赫夫曼树实现字符串编解码(理论) (原创内容,转载请注明来源,谢谢) 一、树和森林 1、树的三种存储结构 1)双亲表示法——数组下标、值...

    用户1327360
  • Elastic Stack 6.8 X-Pack 安全功能部署

    简介 Elastic官方发布消息Elastic Stack 新版本6.8.0 和7.1.0的核心安全功能现免费提供。这意味着用户现在能够对网络流量...

    Kevin song
  • 一个简单的问题 | 分布式副本一致性

    当我们开发大数据应用时, 通常会接触到数据一致性,通常为了提高数据的高可用性,防止单点数据故障,我们会提供数据副本, 这时候冗余副本的数据库一致性问题就是需要考...

    王知无
  • 电信级和网络级光纤跳线的区别是什么?

    光纤跳线为什么要分电信级和网络级呢?为了让大家对这两种级别的产品一目了然,那么今天易天光通信(ETU-LINK)就来讲解一下它们有什么区别吧!

    易天光通信

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动