美文网首页
mongo回顾(十三:writeConcern和readConc

mongo回顾(十三:writeConcern和readConc

作者: supremecsp | 来源:发表于2021-06-15 21:47 被阅读0次

    前段时间杂七杂八的看了mysql和es的知识点,好久没更简书了,今天继续mongo的知识回顾
    之前提到,mongodb的一致性需要借助writeConcern和readConcern的帮忙,且mongo的一切事务都需要手动配置开启,默认事务是没有开启的,为了访问的速度

    首先什么是 writeConcern ?
    writeConcern 决定一个写操作落到多少个节点上才算成功。

    write concern支持3个配置项:
    { w: <value>, j: <boolean>, wtimeout: <number> }

    w的取值包括:
    • 0:发起写操作,不关心是否成功;
    • 1~集群最大数据节点数:写操作需要被复制到指定节点数才算成功;
    • majority:写操作需要被复制到大多数节点上才算成功。
    发起写操作的程序将阻塞到写操作到达指定的节点数为止
    以三个节点的集群为例子
    当配置majority时,大多数节点为2,Primary感知到两个节点被写入完成时就代表成功写入


    majority.png

    j,该参数表示是否写操作要进行journal持久化之后才向用户确认;
    {j: true} 要求primary写操作进行了journal持久化之后才向用户确认;
    {j: false} 要求写操作已经在journal缓存中即可向用户确认;journal后续会将持久化到磁盘,默认是100ms;

    有点类似于mysql的双1配置了,数据必定落盘;
    为什么mysql要双一才能保证事务一致性:
    redo没有及时刷盘,binlog刷盘了,之后瞬间数据库所在主机掉电,主机重启,MySQL重启以后,这个事务会丢失;这里会引起日志和数据不一致。

    wtimeout,该参数表示写入超时时间,w大于1时有效;当w大于1时,写操作需要成功写入若干个节点才算成功,如果写入过程中节点有故障,导致写操作迟迟不能满足w要求,也就一直不能向用户返回确认结果,为了防止这种情况,用户可以设置wtimeout来指定超时时间,写入过程持续超过该时间仍未结束,则认为写入失败。

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

    什么是 readPreference ?
    readPreference 决定使用哪一个节点来满足正在发起的读请求
    可选项有
    primary: 只选择主节点;
    primaryPreferred:优先选择主节点,如
    果不可用则选择从节点;
    secondary:只选择从节点;
    secondaryPreferred:优先选择从节点,如果从节点不可用则选择主节点;
    nearest:选择最近的节点;
    使用格式为db.collection.find({}).readPref( “secondary” )
    若是想控制多个节点可以配合tag使用,具体参考文档,本人暂时这部分没实践过
    https://docs.mongodb.com/manual/core/read-preference/

    什么是 readConcern?

    在 readPreference 选择了指定的节点后,readConcern 决定这个节点上的数据哪些
    是可读的,类似于关系数据库的隔离级别
    格式为:readConcern: { level: <level> }
    可选值包括:
    • available:读取所有可用的数据;
    • local:读取所有可用且属于当前分片的数据;
    • majority:读取在大多数节点上提交完成的数据;
    • linearizable:可线性化读取文档;
    • snapshot:读取最近快照中的数据;

    极客时间中available与local的区别


    极客时间.png

    注意事项:

    1,虽然看上去总是应该选择 local,但毕竟对结果集进行过滤会造成额外消耗。在一些无关紧要的场景(例如统计)下,也可以考虑 available;
    2,MongoDB <=3.6 不支持对从节点使用 {readConcern: "local"};
    3,从主节点读取数据时默认 readConcern 是 local,从从节点读取数据时默认readConcern 是 available(向前兼容原因)

    问题:{readConcern: “majority”}可以避免脏读吗?
    只能极大程度的避免,所谓的脏读可能出现的原因是使用的writeConcern,数据写到从节点后被读取,但是由于系统故障导致最终没写入成功,读取的数据就是脏读了。而{readConcern: “majority”}是从绝大多数拥有数据的节点读取,因此能大程度避免脏读,但是可能出现主节点宕机,或者readConcern写到所有节点才算成功的现象,所以不能完全避免。

    参考文章:https://cloud.tencent.com/developer/article/1624124

    相关文章

      网友评论

          本文标题:mongo回顾(十三:writeConcern和readConc

          本文链接:https://www.haomeiwen.com/subject/yqfaeltx.html