美文网首页alreadymongodb
【mongoDB】mongoDB write-concern、r

【mongoDB】mongoDB write-concern、r

作者: Bogon | 来源:发表于2022-05-02 01:24 被阅读0次

对MongoDB数据库的使用有三种模式:standalone,replica set, sharded cluster。
MongoDB关于一致性、可用性的权衡,取决于三者:write-concern、read-concern、read-preference。

write-concern

write concern表示对于写操作,MongoDB在什么情况下给予客户端响应。包括下面三个字段:

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

w: 表示当写请求在value个MongoDB实例处理之后才向客户端返回。
取值范围:

1:默认值,表示数据写入到standalone的MongoDB或者replica set的primary之后返回;

0:不用写入就直接向客户端返回,性能高,但可能丢数据。不过可以配合j: True来增加数据的可持久性(durability);

>1: 只有在replica set环境下才有用,如果value大于的replica set中节点的数目,那么可能导致阻塞;

‘majority’: 当数据写入到replica set的大多数节点之后向客户端返回,对于这种情况,一般是配合read-concern使用。

After the write operation returns with a w: "majority" acknowledgement to the client, the client can read the result of that write with a "majority" readConcern

j:表示当写请求在写入journal之后才向客户端返回,默认为False。
两点注意:
如果在对于未开启journaling的MongoDB实例使用j:True,会报错;
在MongoDB3.2及之后,对于w>1, 需要所有实例都写到journal之后才返回。

wtimeout:表示写入的超时时间,即在指定的时间(number),如果还不能向客户端返回(w大于1的情况),那么返回错误
默认为0,相当于没有设置该选项。

在MongoDB3.4中,加入了writeConcernMajorityJournalDefault.这么一个选项,使得w,j在不同的组合情况下不同:


image.png

read-concern

read concern是在MongoDB3.2中才加入的新特性,表示对于replica set(包括sharded cluster中使用复制集的shard)返回什么样的数据。
不同的存储引擎对read-concern的支持情况也是不一样的。

read concern有以下三个level:

local:默认值,返回当前节点的最新数据,当前节点取决于read reference;

majority:返回的是已经被确认写入到多数节点的最新数据。该选项的使用需要以下条件: WiredTiger存储引擎,且使用election protocol version 1;启动MongoDB实例的时候指定 --enableMajorityReadConcern选项;

linearizable:3.4版本中引入,这里略过了,感兴趣的读者参考文档。

在文章中有这么一句话:

Regardless of the read concern level, the most recent data on a node may not reflect the most recent version of the data in the system.

就是说,即便使用了read concern:majority, 返回的也不一定是最新的数据,这个和NWR理论并不是一回事。
究其根本原因,在于最终返回的数值只来源于一个MongoDB节点,该节点的选择取决于read reference。

readConcern 的初衷在于解决『脏读』的问题,比如用户从 MongoDB 的 primary 上读取了某一条数据,但这条数据并没有同步到大多数节点,然后 primary 就故障了,重新恢复后 这个primary 节点会将未同步到大多数节点的数据回滚掉,导致用户读到了『脏数据』。
当指定 readConcern 级别为 majority 时,能保证用户读到的数据『已经写入到大多数节点』,而这样的数据肯定不会发生回滚,避免了脏读的问题。

read-reference

一个replica set由一个primary和多个secondary组成。
primary接受写操作,因此数据一定是最新的,secondary通过oplog来同步写操作,因此数据有一定的延迟。
对于时效性不是很敏感的查询业务,可以从secondary节点查询,以减轻集群的压力。

image.png

MongoDB指出在不同的情况下选用不同的read-reference,非常灵活。

MongoDB driver支持一下几种read-reference:
primary:默认模式,一切读操作都路由到replica set的primary节点;
primaryPreferred:正常情况下都是路由到primary节点,只有当primary节点不可用(failover)的时候,才路由到secondary节点;
secondary:一切读操作都路由到replica set的secondary节点;
secondaryPreferred:正常情况下都是路由到secondary节点,只有当secondary节点不可用的时候,才路由到primary节点;
nearest:从延时最小的节点读取数据,不管是primary还是secondary。对于分布式应用且MongoDB是多数据中心部署,nearest能保证最好的data locality。

如果使用secondary或者secondaryPreferred,那么需要意识到:
(1) 因为延时,读取到的数据可能不是最新的,而且不同的secondary返回的数据还可能不一样;
(2) 对于默认开启了balancer的sharded collection,由于还未结束或者异常终止的chunk迁移,secondary返回的可能是有缺失或者多余的数据
(3) 在有多个secondary节点的情况下,选择哪一个secondary节点呢,简单来说是“closest”即平均延时最小的节点
具体参考 Server Selection Algorithm https://www.mongodb.com/docs/manual/core/read-preference-mechanics

一致性 or 可用性?

回顾一下CAP理论中对一致性 可用性的问题:
一致性,是指对于每一次读操作,要么都能够读到最新写入的数据,要么错误。
可用性,是指对于每一次请求,都能够得到一个及时的、非错的响应,但是不保证请求的结果是基于最新写入的数据。

本文对一致性 可用性的讨论是基于replica set的,是否是sharded cluster并不影响。
另外,讨论是基于单个客户端的情况,如果是多个客户端,似乎是隔离性的问题,不属于CAP理论范畴。

基于对write concern、read concern、read reference的理解,我们可以得出以下结论:

默认情况(w:1、readconcern:local),如果read preference为primary,那么是可以读到最新的数据,强一致性;但如果此时primary故障,那么这个时候会返回错误,可用性得不到保证;

默认情况(w:1、readconcern:local),如果read preference为secondary(secondaryPreferred、primaryPreferred),虽然可能读到过时的数据,但能够立刻得到数据,可用性比较好;

writeconern:majority保证写入的数据不会被回滚;
readconcern:majority保证读到的一定是不会被回滚的数据。

若(w:1、readconcern;majority)即使是从primary读取,也不能保证一定返回最新的数据,因此是弱一致性;

若(w: majority、readcocern:majority),如果是从primary读取,那么一定能读到最新的数据,且这个数据一定不会被回滚,但此时写可用性就差一些;如果是从secondary读取,不能保证读到最新的数据,弱一致性。

回过来来看,MongoDB所说的高可用性是更普适意义上的可用性:通过数据的复制和自动failover,即使发生物理故障,整个集群还是能够在短时间内回复,继续工作,何况恢复也是自动的。

从这个意义上,确实是高可用的。

参考

MongoDB writeConcern原理解析
https://developer.aliyun.com/article/54367

MongoDB readConcern 原理解析
https://mongoing.com/archives/3403

CAP理论与MongoDB一致性、可用性的一些思考
https://www.cnblogs.com/xybaby/p/6871764.html

Server Selection Algorithm
https://www.mongodb.com/docs/manual/core/read-preference-mechanics

MongoDB Sharded Cluster 路由策略
https://developer.aliyun.com/article/58689

相关文章

网友评论

    本文标题:【mongoDB】mongoDB write-concern、r

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