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

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

  • 相关阅读:
    matplotlib
    Scipy-数值计算库
    Django Templates
    Django Views: Dynamic Content
    Django Views and URLconfs
    Opencv读写文件
    Logistic回归
    demo
    【Python62--scrapy爬虫框架】
    【Python58--正则2】
  • 原文地址:https://www.cnblogs.com/andy6/p/9838301.html
Copyright © 2020-2023  润新知