• 3.MongoDB的writeConcern模式


    1.WriteConcern

      MongoDB的writeConcern模式简单地可以理解为决定一个写操作落到多少个节点上才算是成功。writerConcern的取值包括:

    • 0:发起写操作,不关心是否成功
    • 1: 默认值,需要等待primary节点完成写操作就可以返回确认写成功的消息
    • n:表示写操作需要被复制到指定节点数才算成功
    • majority:写操作需要被复制到大多数节点上才算成功  

    2.默认模式

      

     majority模式

     All模式

      

    3.WriteConcern中的另一个参数

       j:ture

       writeconcern可以决定写操作到达多少个节点才算成功,journal则定义如何才算成功,设置journal则是保证数据的持久化。取值包括:

    • true:写操作落到journal文件中才算成功(有点类似于Mysql中redo log持久性一样)
    • false:写操作到内存即算成功。

    4.writeConcern中的最后一个参数

      wtimeout参数指定写关注应该在多长时间内返回,如果没有指定这个参数,则复制集可能因为不确定因素导致客户端的写操作一直阻塞

      即使写操作最终会成功写入,但写操作达到这个时间限制时还没完成,也会将相应的错误返回客户端。

      注意:即使写操作最终超时,MongDB也不会撤销在时间限制之前已完成的写操作引起的数据变化。

       

    实验1(一主两从)三节点模式: 

    rs0:PRIMARY> db.test.insert({count:1},{writeConcern:{w:3}})  //这里将w设置为3,表示只要当三个节点都写入成功,才能返回 
    WriteResult({ "nInserted" : 1 })
    
    rs0:PRIMARY> db.test.insert({count:1},{writeConcern:{w:4}})  //这里就有问题,设置了四个节点,但是总共才三个节点
    WriteResult({
        "nInserted" : 1,
        "writeConcernError" : {
            "code" : 100,
            "codeName" : "UnsatisfiableWriteConcern",
            "errmsg" : "Not enough data-bearing nodes",
            "errInfo" : {
                "writeConcern" : {
                    "w" : 4,
                    "wtimeout" : 0,
                    "provenance" : "clientSupplied"
                }
            }
        }
    })
    
    rs0:PRIMARY> db.test.insert({count:1},{writeConcern:{w:"majority"}})   //这里设置的是大多节点。。。。
    WriteResult({ "nInserted" : 1 })

    实验2(延迟设置)

      配置之前的设置

        "members" : [
            {
                "_id" : 1,
                "host" : "127.0.0.1:27017",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(0),
                "votes" : 1
            },
            {
                "_id" : 2,
                "host" : "127.0.0.1:27018",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(0),
                "votes" : 1
            },
            {
                "_id" : 3,
                "host" : "127.0.0.1:27019",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(0),
                "votes" : 1
            }
        ],

    配置延迟之后的配置

    rs0:PRIMARY> conf=rs.conf()
    rs0:PRIMARY> conf.members[1].slaveDelay=5    //单位是秒   这里总是会延迟主节点10秒
    5
    rs0:PRIMARY> conf.members[1].priority=0
    0
    rs0:PRIMARY> rs.reconfig(conf)
        "members" : [
            {
                "_id" : 1,
                "host" : "127.0.0.1:27017",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(0),
                "votes" : 1
            },
            {
                "_id" : 2,
                "host" : "127.0.0.1:27018",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 0,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(5),    //这里看到第二个节点延迟的时间为5秒中
                "votes" : 1
            },
            {
                "_id" : 3,
                "host" : "127.0.0.1:27019",
                "arbiterOnly" : false,
                "buildIndexes" : true,
                "hidden" : false,
                "priority" : 1,
                "tags" : {
                    
                },
                "slaveDelay" : NumberLong(0),
                "votes" : 1
            }
        ],

    这里可以将w这个参数进行数据的插入:

    rs0:PRIMARY> db.test.insertOne({count:4},{writeConcern:{w:3,wtimeout:6000}})   //3000毫秒 --> 3秒

     wtimeout主要是针对客户端防止堵塞情况的,它会判断在该数值范围内,数据是否写到了各个节点(到底要求写进几个节点,主要是看参数w)。

    主要事项

    • 虽然多于半数的writeConcern都是安全的,但通常只会设置majority,因为这是等待写入延迟时间最短的选择
    • 不要设置writeConcern等于总数节点,因为一旦有一个节点故障,所有的写操作都将失败
    • writeConcern虽然会增加写操作延迟时间,但并不会显著增加集群压力,因为无论是否等待,写操作最终都会复制到所有节点上,设置writeConcern只是让写操作等待复制后再返回而已;
    • 应对重要的数据应用{w:"majority"},普通数据可以应用{w:1}以确保最佳性能。 

         

  • 相关阅读:
    访问oss压缩文件失败
    uniapp项目再使用vue-cli启动压缩失败
    航天丰益面试题
    axios上传图片遇见问题
    formateDate
    mongoose中Documents的save方法
    腾讯云nginx配置https
    filter逻辑bug
    vue-infinite-loading 过滤器tab正确使用
    使用pem连接服务器
  • 原文地址:https://www.cnblogs.com/zmc60/p/16181706.html
Copyright © 2020-2023  润新知