readConcern选项允许您控制从复制集和复制集碎片读取的数据的一致性和隔离属性。

通过有效地使用写关注点和读关注点,您可以适当地调整一致性和可用性保证的级别,例如等待更强的一致性保证,或者放松一致性要求以提供更高的可用性。

MongoDB驱动程序更新为MongoDB 3.2或更新后的支持指定读的关注。

阅读关注水平

以下是已阅读的关注程度:

level Description
"local"

该查询返回来自实例的数据,但不能保证数据已被写入大多数复制集成员(即可能回滚)。

默认:

  • reads against primary
  • 如果读操作与任意一致的会话相关联,则对二级读操作执行读操作。

可用性:Read concern local可用于具有或不具有因果一致的会话和事务。

"available"

该查询返回来自实例的数据,但不能保证数据已被写入大多数复制集成员(即可能回滚)。

默认:如果读操作不与一致会话相关联,则对二级服务器执行读操作。

可用性:可用的读关注无法用于因果一致的会话和事务。

对于切分集群,“可用的”读关注点在各种读关注点中提供了尽可能低的延迟读取。然而,这是以牺牲一致性为代价的,因为从切分集合中读取时,“可用的”read关注点可以返回孤立的文档。为了避免从切分集合读取时返回孤立文档的风险,可以使用不同的读取关注点,比如读取关注点“local”。

New in version 3.6.

"majority"

该查询返回已被大多数复制集成员确认的数据。read操作返回的文档是持久的,即使发生故障也是如此。

为了实现读关注“多数”,复制集成员从其在多数提交点的数据内存视图中返回数据。因此,read关注点“多数”在性能成本上与其他read关注点相当。

可用性:

  • Read concern“majority”可用于具有或不具有因果一致的会话和事务。
  • 您可以禁用具有三个成员的主-副-仲裁(PSA)体系结构的部署的read concern“majority”;但是,这对更改流(仅在MongoDB 4.0和更早的版本中)和分片集群上的事务有影响。有关更多信息,请参见禁用读关注多数。

要求:要使用“多数”的读关心级别,副本集必须使用WiredTiger存储引擎。

提示:

对于多文档事务中的操作,只有在事务提交时写入关注“多数”时,读关注“多数”才提供它的保证。否则,“大多数”读关注点不能保证在事务中读取数据。

"linearizable"

该查询返回的数据反映了在开始读操作之前完成的所有成功的、多数已确认的写操作。在返回结果之前,查询可以等待并发执行的写传播到大多数复制集成员。

如果您的大多数复制集成员在读操作之后崩溃并重新启动,那么如果writeConcernMajorityJournalDefault设置为true的默认状态,那么读操作返回的文档将是持久的。

当writeConcernMajorityJournalDefault设置为false时,MongoDB不会在确认写操作之前等待w:“majority”写操作被写到磁盘上的日志中。因此,如果给定副本集中的大多数节点发生暂时丢失(例如崩溃和重新启动),大多数写操作可能会回滚。

可用性:

  • 读取关注“线性化”无法用于因果一致的会话和事务。
  • 您可以仅为主节点上的读操作指定可线性化的读关注点。

您不能将$out或$merge阶段与read关注点“linearizable”一起使用。也就是说,如果指定db.collection.aggregate()的read关注点为“linearizable”,则不能在管道中包含这两个阶段。

需求:可线性化的read关注点保证只在read操作指定唯一标识单个文档的查询过滤器时才适用。

Tip

在大多数数据承载成员不可用的情况下,总是将maxTimeMS与可线性化的读关系一起使用。unavailable. maxTimeMS确保操作不会无限期阻塞,而是确保如果无法满足读关注,则操作返回一个错误。

"snapshot"

如果事务不是一个偶然一致的会话的一部分,那么在事务提交时,如果事务关注“大多数”,那么事务操作就可以从大量提交数据的快照中读取数据。

如果事务是因果一致的会话的一部分,那么在事务提交时,如果事务涉及“多数”,那么事务操作将保证已经读取了多数提交数据的快照,该快照提供了与事务开始之前的操作的因果一致性。

可用性:

  • “快照”仅可用于多文档事务。
  • 对于分片集群上的事务,如果事务中的任何操作涉及到已禁用了read concern“majority”的碎片,则不能对事务使用read concern“snapshot”。对于事务,您只能使用read concern“local”或“majority”。

无论读取的关注级别如何,节点上的最新数据可能不会反映系统中数据的最新版本。

2.readConcern支持

2.1 Read Concern Option¶

对于不在多文档事务中的操作,您可以指定readConcern级别,作为支持read concern的命令和方法的选项:

readConcern: { level: <level> }

要为mongo shell方法db.collection.find()指定读关注级别,请使用指针. readconcern()方法:

db.collection.find().readConcern(<level>)

2.2 事务和可用的读关注点

对于多文档事务,您可以在事务级别设置read关注点,而不是在单个操作级别。事务中的操作将使用事务级读关注点。在集合和数据库级别上的任何读关注集都将在事务内部被忽略。如果显式地指定了事务级别的读关注,那么在事务内部也会忽略客户端级别的读关注。

重要:

不要显式地设置单个操作的读关注点。要设置事务的读关注,请参阅读关注/写关注/读首选项。

你可以在事务开始时设置read concern:

  • 对于多文档事务,可以读取“快照”、“本地”和“多数”关注级别。
  • 作为多文档事务一部分的写命令可以支持事务级别的读取。

如果在事务开始时未指定,事务将使用会话级别的读关注,如果未设置,则使用客户端级别的读关注。

2.3 因果一致的会话和可用的Read关注点

对于因果一致会话中的操作,可以使用“局部”和“多数”级别。然而,为了保证因果一致性,你必须使用“多数”。详情请参阅因果一致性。
如果一个多文档事务与一个偶然一致的会话相关联,那么该事务也可以使用“快照”。

2.4 支持读关注点的操作

以下操作支持读关注:

重要:要设置事务中操作的读关注,您需要在事务级别设置读关注,而不是在单个操作级别。不要显式地设置事务中各个操作的读关注点。

transaction. For more information, see Transactions and Read Concern.

Command/Method "local" "available" "majority" "snapshot" [3] "linearizable"
count  
distinct ✓ [2]
find
db.collection.find() via cursor.readConcern()
geoSearch
getMore      
aggregate db.collection.aggregate() ✓ [1]
Session.startTransaction()    

[1] 您不能将$out或$merge阶段与read关注点“linearizable”一起使用。也就是说,如果指定db.collection.aggregate()的read关注点为“linearizable”,则不能在管道中包含这两个阶段。

[2]“快照”仅对多文档事务可用。在事务中,不能在切分的集合上使用不同的命令或其帮助程序。

如果是多文档事务的一部分,下面的写操作也可以接受读关注:

重要:要设置事务中操作的读关注,您需要在事务级别设置读关注,而不是在单个操作级别。

Command "local" "available" "majority" "snapshot" [3] "linearizable"

delete

db.collection.deleteMany()

db.collection.deleteOne()

db.collection.remove()

     

findAndModify

db.collection.findAndModify()

db.collection.findOneAndDelete()

db.collection.findOneAndReplace()

db.collection.findOneAndUpdate()

     

insert

db.collection.insert()

db.collection.insertOne()

db.collection.insertMany()

     

update

db.collection.update()

db.collection.updateMany()

db.collection.updateOne()

db.collection.replaceOne()

     

[3] “快照”仅对多文档事务可用,对于事务,您在事务级别设置读关注。支持“快照”的操作对应于事务中可用的CRUD操作。有关更多信息,请参见事务并阅读关注点。

3. 注意事项

3.1 读取你自己写的内容

在3.6版本中进行了更改。
从MongoDB 3.6开始,如果写请求确认,您可以使用因果一致的会话来读取自己的写。

在MongoDB 3.6之前,你必须使用{w: "majority"}写关注点来发布你的写操作,然后使用"majority"或"linearizable"读关注点来进行读操作,以确保单个线程可以读它自己的写。

3.2 根据顺序实时读取

与“多数”写关注点相结合,“线性化”读关注点使多个线程能够对单个文档执行读写操作,就像一个线程实时执行这些操作一样;也就是说,这些读写的相应调度被认为是可线性化的。

3.3 性能比较

与“多数”不同,“可线性化”的读关心向次要成员确认读操作是从主成员读取的,主成员能够用{w:“多数”}写关心来确认写。因此,使用线性化读关注点的读取速度可能比使用“多数”或“局部”读关注点的读取慢得多。

在大多数数据承载成员不可用的情况下,总是将maxTimeMS与可线性化的读关系一起使用。maxTimeMS确保操作不会无限期阻塞,而是确保如果无法满足读关注,则操作返回一个错误。

举例:

db.restaurants.find( { _id: 5 } ).readConcern("linearizable").maxTimeMS(10000)db.runCommand( {find: "restaurants",filter: { _id: 5 },readConcern: { level: "linearizable" },maxTimeMS: 10000
} )

【4】 在某些情况下,复制集中的两个节点可能会暂时认为它们是主节点,但最多其中一个能够使用{w: "majority"} write concern完成写操作。可以完成{w: "majority"}写操作的节点是当前的主节点,其他节点是以前的主节点,还没有意识到它的降级,通常是由于网络分区。当发生这种情况时,连接到前一个主服务器的客户端可能会观察到过时的数据,尽管已经请求了read preference主服务器,并且对前一个主服务器的新写操作最终将回滚。

3.4 读取操作和集群时间

新版本3.6。
MongoDB 3.6引入了对因果一致性会话的支持。对于与因果一致性会话相关的读操作,MongoDB 3.6引入了afterClusterTime读关注选项,该选项由与因果一致性会话相关的操作的驱动程序自动设置。

重要:
不要手动设置读操作的afterClusterTime。MongoDB驱动程序会自动为与因果一致性会话相关的操作设置这个值。但是,可以提前会话的操作时间和集群时间,比如与另一个客户机会话的操作保持一致。有关示例,请参见示例。

要满足一个afterClusterTime值为T的读请求,mongod必须在它的oplog到达时间T之后执行请求。如果它的oplog没有到达时间T, mongod必须等待服务请求。
使用指定的afterClusterTime的读操作返回的数据同时满足Read关注级需求和指定的afterClusterTime需求。
对于与因果一致性会话无关的读操作,afterClusterTime未设置。

一. Read Concern "local"

带有read关注点“local”的查询返回来自实例的数据,但不能保证数据已被写入大多数复制集成员(即可能回滚)。

Read concern“local”是以下情况的默认值:

  • 主读操作
  • 如果读操作与因果一致的会话相关联,则对二级服务器执行读操作。

无论读取的关注级别如何,节点上的最新数据可能不会反映系统中数据的最新版本。

1.可用性

Read concern local可用于具有或不具有因果一致的会话和事务。

2. Read Concern "local" and Transactions¶

在事务级别设置了read关注点,而不是在单个操作级别。要设置事务的读关注点,请参阅事务和读关注点。

3. 举例

考虑写入操作Write0到一个三成员副本集的时间轴:

请注意
为了简化,这个例子假设:

  • Write0之前的所有写操作都已成功复制到所有成员。
  • Writeprev是Write0之前的前一个写。
  • 写0之后没有发生其他写操作。

Time Event Most Recent Write Most Recent w: “majority” write
t0 Primary applies Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t1 Secondary1 applies write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t2 Secondary2 applies write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t3 Primary is aware of successful replication to Secondary1 and sends acknowledgement to client

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t4 Primary is aware of successful replication to Secondary2

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t5 Secondary1 receives notice (through regular replication mechanism) to update its snapshot of its most recent w: “majority” write

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

t6 Secondary2 receives notice (through regular replication mechanism) to update its snapshot of its most recent w: “majority” write

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

然后,下面的表总结了具有“本地”读关注点的读操作在T时刻看到的数据状态。

Read Target Time T State of Data
Primary After t0 Data reflects Write0.
Secondary1 Before t1 Data reflects Writeprev
Secondary1 After t1 Data reflects Write0
Secondary2 Before t2 Data reflects Writeprev
Secondary2 After t2 Data reflects Write0

二 Read Concern "available"

新版本3.6。

带有read关注点“available”的查询返回来自实例的数据,但不能保证数据已被写入大多数复制集成员(即可能回滚)。

读关注点“available”是针对次要服务器的读操作的默认值,如果读操作没有与因果一致的会话关联的话。

对于sharded集群,“available”read关注点为分区提供了更大的容忍度,因为它不会等待以确保一致性保证。也就是说,对于更新的元数据,read关注点“available”既不与shard的主服务器联系,也不与配置服务器联系。但是,这意味着如果碎片正在进行块迁移,那么具有“可用”read关注点的查询可能会返回孤立的文档。

如果碎片正在进行块迁移,则可能返回孤立的文档。
对于未切分的集合(包括独立部署或复制集部署中的集合),“本地”和“可用”读关注的行为是相同的。
无论读取的关注级别如何,节点上的最新数据可能不会反映系统中数据的最新版本。

1. Availability

可用的读关注无法用于因果一致的会话和事务。

2. 例子

考虑写入操作Write0到一个三成员副本集的时间轴:

提示:

为了简化,这个例子假设:

  • Write0之前的所有写操作都已成功复制到所有成员。
  • Writeprev是Write0之前的前一个写。
  • 写0之后没有发生其他写操作。

Time Event Most Recent Write Most Recent w: “majority” write
t0 Primary 适用Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t1 Secondary1适用write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t2 Secondary2适用write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t3 Primary感知到成功复制到Secondary1,并向客户机发送确认

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t4 主节点感知到成功复制到Secondary2

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t5 Secondary1收到通知(通过常规的复制机制)更新其最新w:“majority”写入的快照

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

t6 Secondary2收到通知(通过常规复制机制)更新其最新w:“majority”写入的快照

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

然后,下表总结了具有“available”read关注点的read操作在T时刻看到的数据状态。

Read Target Time T State of Data
Primary After t0 Data reflects Write0.
Secondary1 Before t1 Data reflects Writeprev
Secondary1 After t1 Data reflects Write0
Secondary2 Before t2 Data reflects Writeprev
Secondary2 After t2 Data reflects Write0

三、Read Concern "majority"

对于与多文档事务无关的读操作,读关注点“多数”保证读到的数据已被大多数复制集成员确认(即读到的文档是持久的,保证不会回滚)。

对于多文档事务中的操作,只有在事务提交时写入关注“多数”时,读关注“多数”才提供它的保证。否则,“大多数”读关注点不能保证在事务中读取数据。
无论读取的关注级别如何,节点上的最新数据可能不会反映系统中数据的最新版本。

1. Performance

每个复制集成员在内存中维护一个数据在主提交点的视图;主要提交点由主节点计算。为了实现读关注点“多数”,节点从这个视图返回数据,并且在性能成本上与其他读关注点相当。

2. Availability

Read concern“majority”可用于具有或不具有因果一致的会话和事务。
您可以禁用具有三个成员的主-副-仲裁(PSA)体系结构的部署的read concern“majority”;但是,这对更改流(仅在MongoDB 4.0和更早的版本中)和分片集群上的事务有影响。有关更多信息,请参见禁用读关注多数。

3. Example

考虑写入操作Write0到一个三成员副本集的时间轴:

注意
为了简化,这个例子假设:

  • Write0之前的所有写操作都已成功复制到所有成员。
  • Writeprev是Write0之前的前一个写。
  • 写0之后没有发生其他写操作。

Time Event Most Recent Write Most Recent w: “majority” write
t0 Primary applies Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t1 Secondary1 applies write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t2 Secondary2 applies write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t3 Primary is aware of successful replication to Secondary1 and sends acknowledgement to client

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t4 Primary is aware of successful replication to Secondary2

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t5 Secondary1 receives notice (through regular replication mechanism) to update its snapshot of its most recent w: “majority” write

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

t6 Secondary2 receives notice (through regular replication mechanism) to update its snapshot of its most recent w: “majority” write

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

然后,下面的表总结了具有“多数”读关注的读操作在T时刻看到的数据状态。

Read Target Time T State of Data
Primary Before t3 Data reflects Writeprev
Primary After t3 Data reflects Write0
Secondary1 Before t5 Data reflects Writeprev
Secondary1 After t5 Data reflects Write0
Secondary2 Before or at t6 Data reflects Writeprev
Secondary2 After t6 Data reflects Write0

4. 存储引擎支持

对于WiredTiger存储引擎来说,Read concern“majority”是可用的。

提示
serverStatus命令返回存储引擎。supportsCommittedReads字段,该字段指示存储引擎是否支持“多数”读关注点。

5. Read Concern "majority" and Transactions

请注意
您在事务级别设置了read关注点,而不是在单个操作级别。要设置事务的读关注点,请参阅事务和读关注点。

对于多文档事务中的操作,只有在事务提交时写入关注“多数”时,读关注“多数”才提供它的保证。否则,“大多数”读关注点不能保证在事务中读取数据。

6. Read Concern "majority" and Aggregation¶

从MongoDB 4.2开始,您可以为包含$out阶段的聚合指定read关注点级别“majority”。
在MongoDB 4.0和更早的版本中,您不能包含$out阶段来使用“多数”读关心的聚合。

7. Read Your Own Writes

在3.6版本中进行了更改。
从MongoDB 3.6开始,如果写请求确认,您可以使用因果一致的会话来读取自己的写。
在MongoDB 3.6之前,你必须使用{w: "majority"}写关注点来发布你的写操作,然后使用"majority"或"linearizable"读关注点来进行读操作,以确保单个线程可以读它自己的写。

请注意
如果您使用的是除3人PSA以外的部署,则不需要禁用read concern majority。

对于三成员PSA架构,如果任何数据承载节点出现故障,缓存压力将会增加。为了防止存储缓存压力固定一个部署与PSA架构,您可以禁用读关心通过设置:

  • --enableMajorityReadConcern命令行选项为false。
  • replication.enableMajorityReadConcern配置文件设置为false。

要检查是否禁用了read关注点“majority”,可以在mongod实例上运行db.serverStatus()并检查存储引擎。supportsCommittedReads字段。如为假,则阅读关系“多数”被禁用。

重要的
一般来说,除非必要,避免禁用“多数”读关心。但是,如果您有一个具有主-次-仲裁(PSA)体系结构的三成员副本集,或者一个具有三成员PSA碎片的分片集群,则禁用它以防止存储缓存压力使部署无法进行。

改变流
禁用“多数”读关注会禁用对MongoDB 4.0及更早版本的更改流的支持。对于MongoDB 4.2+,禁用read concern“majority”对变更流可用性没有影响。

事务
禁用“多数”读关注会影响对切分集群上事务的支持。具体地说:

  • 如果事务涉及的碎片已禁用了读关注“多数”,则事务不能使用读关注“快照”。
  • 如果事务的任何读或写操作涉及到已禁用读的切分,则向多个切分写入错误的事务与“多数”有关。

但是,它不会影响复制集上的事务。对于副本集上的事务,您可以为多文档事务指定读关注“多数”(或“快照”或“本地”),即使已禁用读关注“多数”。

四、Read Concern "linearizable"

新版本3.4。
该查询返回的数据反映了在开始读操作之前完成的所有成功的、多数已确认的写操作。在返回结果之前,查询可以等待并发执行的写传播到大多数复制集成员。

如果您的大多数复制集成员在读操作之后崩溃并重新启动,那么如果writeConcernMajorityJournalDefault设置为true的默认状态,那么读操作返回的文档将是持久的。

当writeConcernMajorityJournalDefault设置为false时,MongoDB不会在确认写操作之前等待w:“majority”写操作被写到磁盘上的日志中。因此,如果给定副本集中的大多数节点发生暂时丢失(例如崩溃和重新启动),大多数写操作可能会回滚。

您可以仅为主节点上的读操作指定可线性化的读关注点。
可线性化的read关注点保证只在read操作指定唯一标识单个文档的查询筛选器时应用。

提示
在大多数数据承载成员不可用的情况下,总是将maxTimeMS与可线性化的读关系一起使用。maxTimeMS确保操作不会无限期阻塞,而是确保如果无法满足读关注,则操作返回一个错误。

1. 有原因地一致的会话

Read concern linearizable不能用于因果一致的会话。

2. 聚合的限制

您不能将$out或$merge阶段与read关注点“linearizable”一起使用。也就是说,如果指定db.collection.aggregate()的read关注点为“linearizable”,则不能在管道中包含这两个阶段。

3. Real Time Order

与“多数”写关注点相结合,“线性化”读关注点使多个线程能够对单个文档执行读写操作,就像一个线程实时执行这些操作一样;也就是说,这些读写的相应调度被认为是可线性化的。

4. Read Your Own Writes

在3.6版本中进行了更改。
从MongoDB 3.6开始,如果写请求确认,您可以使用因果一致的会话来读取自己的写。

在MongoDB 3.6之前,你必须使用{w: "majority"}写关注点来发布你的写操作,然后使用"majority"或"linearizable"读关注点来进行读操作,以确保单个线程可以读它自己的写。

5. 性能比较

与“多数”不同,“可线性化”的读关心向次要成员确认读操作是从主成员读取的,主成员能够用{w:“多数”}写关心来确认写。因此,使用线性化读关注点的读取速度可能比使用“多数”或“局部”读关注点的读取慢得多。

在大多数数据承载成员不可用的情况下,总是将maxTimeMS与可线性化的读关系一起使用。maxTimeMS确保操作不会无限期阻塞,而是确保如果无法满足读关注,则操作返回一个错误。

举例:

db.restaurants.find( { _id: 5 } ).readConcern("linearizable").maxTimeMS(10000)db.runCommand( {find: "restaurants",filter: { _id: 5 },readConcern: { level: "linearizable" },maxTimeMS: 10000
} )

在某些情况下,复制集中的两个节点可能会暂时认为它们是主节点,但最多其中一个能够使用{w: "majority"} write concern完成写操作。可以完成{w: "majority"}写操作的节点是当前的主节点,其他节点是以前的主节点,还没有意识到它的降级,通常是由于网络分区。当发生这种情况时,连接到前一个主服务器的客户端可能会观察到过时的数据,尽管已经请求了read preference主服务器,并且对前一个主服务器的新写操作最终将回滚。

五、Read Concern "majority"

对于与多文档事务无关的读操作,读关注点“多数”保证读到的数据已被大多数复制集成员确认(即读到的文档是持久的,保证不会回滚)。

对于多文档事务中的操作,只有在事务提交时写入关注“多数”时,读关注“多数”才提供它的保证。否则,“大多数”读关注点不能保证在事务中读取数据。
无论读取的关注级别如何,节点上的最新数据可能不会反映系统中数据的最新版本。

1. Performance

每个复制集成员在内存中维护一个数据在主提交点的视图;主要提交点由主节点计算。为了实现读关注点“多数”,节点从这个视图返回数据,并且在性能成本上与其他读关注点相当。

2. Availability

Read concern“majority”可用于具有或不具有因果一致的会话和事务。
您可以禁用具有三个成员的主-副-仲裁(PSA)体系结构的部署的read concern“majority”;但是,这对更改流(仅在MongoDB 4.0和更早的版本中)和分片集群上的事务有影响。有关更多信息,请参见禁用读关注多数。

3. 例子

考虑写入操作Write0到一个三成员副本集的时间轴:

请注意
为了简化,这个例子假设:

  • Write0之前的所有写操作都已成功复制到所有成员。
  • Writeprev是Write0之前的前一个写。
  • 写0之后没有发生其他写操作。

Time Event Most Recent Write Most Recent w: “majority” write
t0 Primary applies Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t1 Secondary1 applies write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t2 Secondary2 applies write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Writeprev

Secondary1: Writeprev

Secondary2: Writeprev

t3 Primary is aware of successful replication to Secondary1 and sends acknowledgement to client

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t4 Primary is aware of successful replication to Secondary2

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Writeprev

Secondary2: Writeprev

t5 Secondary1 receives notice (through regular replication mechanism) to update its snapshot of its most recent w: “majority” write

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Writeprev

t6 Secondary2 receives notice (through regular replication mechanism) to update its snapshot of its most recent w: “majority” write

Primary: Write0

Secondary1: Write0

Secondary2: Write0

Primary: Write0

Secondary1: Write0

Secondary2: Write0

然后,下面的表总结了具有“多数”读关注的读操作在T时刻看到的数据状态。

Read Target Time T State of Data
Primary Before t3 Data reflects Writeprev
Primary After t3 Data reflects Write0
Secondary1 Before t5 Data reflects Writeprev
Secondary1 After t5 Data reflects Write0
Secondary2 Before or at t6 Data reflects Writeprev
Secondary2 After t6 Data reflects Write0

4. Storage Engine Support

对于WiredTiger存储引擎来说,Read concern“majority”是可用的。

提示
serverStatus命令返回存储引擎。supportsCommittedReads字段,该字段指示存储引擎是否支持“多数”读关注点。

5. Read Concern "majority" and Transactions

请注意
您在事务级别设置了read关注点,而不是在单个操作级别。要设置事务的读关注点,请参阅事务和读关注点。

对于多文档事务中的操作,只有在事务提交时写入关注“多数”时,读关注“多数”才提供它的保证。否则,“大多数”读关注点不能保证在事务中读取数据。

6. Read Concern "majority" and Aggregation

从MongoDB 4.2开始,您可以为包含$out阶段的聚合指定read关注点级别“majority”。
在MongoDB 4.0和更早的版本中,您不能包含$out阶段来使用“多数”读关心的聚合。

7. Read Your Own Writes

在3.6版本中进行了更改。
从MongoDB 3.6开始,如果写请求确认,您可以使用因果一致的会话来读取自己的写。
在MongoDB 3.6之前,你必须使用{w: "majority"}写关注点来发布你的写操作,然后使用"majority"或"linearizable"读关注点来进行读操作,以确保单个线程可以读它自己的写。

8. Disable Read Concern Majority

适用于3人主-副-仲裁架构
如果您有一个具有主-次-仲裁(PSA)体系结构的三成员副本集,或者一个具有三成员PSA碎片的分片集群,您可以禁用read concern“majority”。

请注意
如果您使用的是除3人PSA以外的部署,则不需要禁用read concern majority。

对于三成员PSA架构,如果任何数据承载节点出现故障,缓存压力将会增加。为了防止存储缓存压力固定一个部署与PSA架构,您可以禁用读关心通过设置:

  • --enableMajorityReadConcern command line option to false.
  • replication.enableMajorityReadConcern configuration file setting to false.

要检查是否禁用了read关注点“majority”,可以在mongod实例上运行db.serverStatus()并检查存储引擎。supportsCommittedReads字段。如为假,则阅读关系“多数”被禁用。

重要的
一般来说,除非必要,避免禁用“多数”读关心。但是,如果您有一个具有主-次-仲裁(PSA)体系结构的三成员副本集,或者一个具有三成员PSA碎片的分片集群,则禁用它以防止存储缓存压力使部署无法进行。

改变流
禁用“多数”读关注会禁用对MongoDB 4.0及更早版本的更改流的支持。对于MongoDB 4.2+,禁用read concern“majority”对变更流可用性没有影响。

事务
禁用“多数”读关注会影响对切分集群上事务的支持。具体地说:

  • 如果事务涉及的碎片已禁用了读关注“多数”,则事务不能使用读关注“快照”。
  • 如果事务的任何读或写操作涉及到已禁用读的切分,则向多个切分写入错误的事务与“多数”有关。

但是,它不会影响复制集上的事务。对于副本集上的事务,您可以为多文档事务指定读关注“多数”(或“快照”或“本地”),即使已禁用读关注“多数”。

六、Read Concern "linearizable"

新版本3.4。
该查询返回的数据反映了在开始读操作之前完成的所有成功的、多数已确认的写操作。在返回结果之前,查询可以等待并发执行的写传播到大多数复制集成员。

如果您的大多数复制集成员在读操作之后崩溃并重新启动,那么如果writeConcernMajorityJournalDefault设置为true的默认状态,那么读操作返回的文档将是持久的。
当writeConcernMajorityJournalDefault设置为false时,MongoDB不会在确认写操作之前等待w:“majority”写操作被写到磁盘上的日志中。因此,如果给定副本集中的大多数节点发生暂时丢失(例如崩溃和重新启动),大多数写操作可能会回滚。

您可以仅为主节点上的读操作指定可线性化的读关注点。
可线性化的read关注点保证只在read操作指定唯一标识单个文档的查询筛选器时应用。

提示
在大多数数据承载成员不可用的情况下,总是将maxTimeMS与可线性化的读关系一起使用。maxTimeMS确保操作不会无限期阻塞,而是确保如果无法满足读关注,则操作返回一个错误。

1. 有原因地一致的会话

Read concern linearizable不能用于因果一致的会话。

2. 聚合的限制

您不能将$out或$merge阶段与read关注点“linearizable”一起使用。也就是说,如果指定db.collection.aggregate()的read关注点为“linearizable”,则不能在管道中包含这两个阶段。

3. Real Time Order¶

与“多数”写关注点相结合,“线性化”读关注点使多个线程能够对单个文档执行读写操作,就像一个线程实时执行这些操作一样;也就是说,这些读写的相应调度被认为是可线性化的。

4. Read Your Own Writes¶

在3.6版本中进行了更改。
从MongoDB 3.6开始,如果写请求确认,您可以使用因果一致的会话来读取自己的写。
在MongoDB 3.6之前,你必须使用{w: "majority"}写关注点来发布你的写操作,然后使用"majority"或"linearizable"读关注点来进行读操作,以确保单个线程可以读它自己的写。

5. 性能比较

与“多数”不同,“可线性化”的读关心向次要成员确认读操作是从主成员读取的,主成员能够用{w:“多数”}写关心来确认写。因此,使用线性化读关注点的读取速度可能比使用“多数”或“局部”读关注点的读取慢得多。

在大多数数据承载成员不可用的情况下,总是将maxTimeMS与可线性化的读关系一起使用。maxTimeMS确保操作不会无限期阻塞,而是确保如果无法满足读关注,则操作返回一个错误。

举例:

db.restaurants.find( { _id: 5 } ).readConcern("linearizable").maxTimeMS(10000)db.runCommand( {find: "restaurants",filter: { _id: 5 },readConcern: { level: "linearizable" },maxTimeMS: 10000
} )

在某些情况下,复制集中的两个节点可能会暂时认为它们是主节点,但最多其中一个能够使用{w: "majority"} write concern完成写操作。可以完成{w: "majority"}写操作的节点是当前的主节点,其他节点是以前的主节点,还没有意识到它的降级,通常是由于网络分区。当发生这种情况时,连接到前一个主服务器的客户端可能会观察到过时的数据,尽管已经请求了read preference主服务器,并且对前一个主服务器的新写操作最终将回滚。

七、Read Concern "snapshot"

新版本4.0。
“快照”只适用于多文档事务。

  • 如果事务不是一个偶然一致的会话的一部分,那么在事务提交时,如果事务关注“大多数”,那么事务操作就可以从大量提交数据的快照中读取数据。
  • 如果事务是因果一致的会话的一部分,那么在事务提交时,如果事务涉及“多数”,那么事务操作将保证已经读取了多数提交数据的快照,该快照提供了与事务开始之前的操作的因果一致性。

1. 操作

有关接受读关注点的所有操作的列表,请参阅支持读关注点的操作。

2. 有关接受读关注点的所有操作的列表,请参阅支持读关注点的操作。

多文档事务支持读取关注点“快照”以及“本地”和“多数”。

请注意
您在事务级别设置了read关注点,而不是在单个操作级别。要设置事务的读关注点,请参阅事务和读关注点。

对于分片集群上的事务,如果事务中的任何操作涉及到已禁用了read concern“majority”的碎片,则不能对事务使用read concern“snapshot”。对于事务,您只能使用read concern“local”或“majority”。如果使用“快照”,则事务错误和中止。有关更多信息,请参见禁用阅读关注多数。

八、Write Concern

Write concern描述从MongoDB请求的写入操作到独立mongod、复制集或切分集群的确认级别。在切分的集群中,mongos实例将写关注点传递给切分。

请注意
对于多文档事务,您可以在事务级别设置写关注点,而不是在单个操作级别。不要显式地为事务中的各个写操作设置写关系。

1. 写关注规范

Write关注点可以包括以下字段:

{ w: <value>, j: <boolean>, wtimeout: <number> }
  • 请求确认写操作已传播到指定数量的mongod实例或具有指定标记的mongod实例的w选项。
  • j选项请求确认写入操作已被写入磁盘日志,
  • wtimeout选项指定时间限制以防止写入操作无限期阻塞。

1.1 w选项

w选项请求确认写操作已传播到指定数量的mongod实例或具有指定标记的mongod实例。

使用w选项,以下w: <value> write concerns are available:

Value Description

<number>

Requests acknowledgment that the write operation has propagated to the specified number of mongod instances. For example:

w: 1

Requests acknowledgment that the write operation has propagated to the standalone mongod or the primary in a replica set. w: 1 is the default write concern for MongoDB.

w: 0

Requests no acknowledgment of the write operation. However, w: 0 may return information about socket exceptions and networking errors to the application.

If you specify w: 0 but include j: true, the j: true prevails to request acknowledgment from the standalone mongod or the primary of a replica set.

w greater than 1 requires acknowledgment from the primary and as many additional data-bearing secondaries to meet the specified write concern. For example, consider a 3-member replica set with no arbiters. Specifying w: 2 would require acknowledgment from the primary and one of the secondaries. Specifying w: 3 would require acknowledgment from the primary and both secondaries.

Note

Hidden, delayed, and priority 0 members can acknowledge w: <number> write operations.

Delayed secondaries can return write acknowledgment no earlier than the configured slaveDelay.

See Acknowledgment Behavior for when mongod instances acknowledge the write.

"majority"

Requests acknowledgment that write operations have propagated to the calculated majority of the data-bearing voting members (i.e. primary and secondaries with members[n].votes greater than 0).

For example, consider a replica set with 3 voting members, Primary-Secondary-Secondary (P-S-S). For this replica set, calculated majority is two, and the write must propagate to the primary and one secondary to acknowledge the write concern to the client.

Note

Hidden, delayed, and priority 0 members with members[n].votes greater than 0 can acknowledge "majority" write operations.

Delayed secondaries can return write acknowledgment no earlier than the configured slaveDelay.

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

See Acknowledgment Behavior for when mongod instances acknowledge the write.

<custom write concern name>

Requests acknowledgment that the write operations have propagated to tagged members that satisfy the custom write concern defined in settings.getLastErrorModes.

For an example, see Custom Multi-Datacenter Write Concerns.

See Acknowledgment Behavior for when mongod instances acknowledge the write.

1.2 j选项

j选项请求MongoDB确认写入操作已经写入到磁盘上的日志。

如果j: true,请求确认在w: <value>中指定的mongod实例已写入磁盘日志。j: true本身不能保证写操作不会因为副本集主故障转移而回滚。

在版本3.2:用j: true修改后,MongoDB只在请求的成员数量(包括主成员)写入日志之后才返回。以前,在一个复制集中,j: true write concern只需要主写日志,而不管w: <value> write concern。

 

请注意

  • 指定一个写关注点(包括j: true)到一个运行没有日志记录的mongod实例会产生一个错误。
  • 如果启用了日志记录,w:“多数”可能意味着j:是真的。writeConcernMajorityJournalDefault复制集配置设置确定行为。有关详细信息,请参见确认行为。

1.3 超时

此选项指定写入关注的时间限制(以毫秒为单位)。wtimeout只适用于大于1的w值。

wtimeout导致写操作在指定的限制之后返回一个错误,即使所需的写关注最终会成功。当这些写操作返回时,MongoDB不会撤销在写操作超出wtimeout时间限制之前执行的成功数据修改。

如果您没有指定wtimeout选项,并且写关心的级别无法达到,那么写操作将无限期阻塞。将wtimeout值指定为0等同于不使用wtimeout选项的写关注点。

2. Acknowledgment Behavior

w选项和j选项确定mongod实例何时确认写操作。

2.1 独立的

一个独立的mongod在将写操作应用到内存中或写入到磁盘日志后确认一个写操作。下表列出了单机的确认行为和相关的写问题:

  j is unspecified j:true j:false
w: 1 In memory On-disk journal In memory
w: "majority" On-disk journal if running with journaling On-disk journal In memory

请注意
当writeConcernMajorityJournalDefault设置为false时,MongoDB不会在确认写操作之前等待w:“majority”写操作被写到磁盘上的日志中。因此,如果给定副本集中的大多数节点发生暂时丢失(例如崩溃和重新启动),大多数写操作可能会回滚。

2.2 复制集

指定给w的值决定了在返回成功之前必须确认写入的复制集成员的数量。对于每个合格的复制集成员,j选项确定该成员是在内存中应用写操作后确认写操作,还是在对磁盘日志进行写操作后确认写操作。

w:“大多数”
复制集的任何带有数据的投票成员都可以对“多数”写操作的写确认做出贡献。

下表列出了成员何时可以根据j值确认写操作:

j is unspecified

确认取决于writeConcernMajorityJournalDefault的值::

  • 如果为真,确认需要对磁盘日志进行写操作(j:为真)。
    writeConcernMajorityJournalDefault默认为true

  • 如果为假,确认需要在内存中执行写操作(j: false)。

j: true 确认需要向磁盘日志写入操作。
j: false 确认需要在内存中执行写入操作。

请注意
当writeConcernMajorityJournalDefault设置为false时,MongoDB不会在确认写操作之前等待w:“majority”写操作被写到磁盘上的日志中。因此,如果给定副本集中的大多数节点发生暂时丢失(例如崩溃和重新启动),大多数写操作可能会回滚。

请注意
具有成员的隐藏、延迟和优先级为0的成员[n]。大于0的投票可以确认“多数”写操作。
延迟的二级服务器可以不早于配置的slaveDelay返回写应答。

w: <number>

任何数据成员的副本集可以贡献写确认w: <number>写操作。

下表列出了成员何时可以根据j值确认写操作:

j is unspecified 确认需要在内存中执行写入操作(j: false)。
j: true 确认需要向磁盘日志写入操作。
j: false 确认需要在内存中执行写入操作.

请注意
隐藏、延迟和优先级为0的成员可以确认w: <number>写操作。
延迟的二级服务器可以不早于配置的slaveDelay返回写应答。

3.Calculating Majority for Write Concern

从版本4.2.1开始,rs.status()返回writeMajorityCount字段,该字段包含计算得到的大多数数字。

对于写关心的“多数”计算如下值中较小的值:

  • 所有投票成员的多数(包括仲裁者)vs。
  • 所有有数据的投票成员的数目。

警告
如果计算出的多数票数目等于所有具有数据的投票成员的数目(例如具有3个成员的主-副-仲裁服务器的部署),则写入关注“多数票”可能超时,或者如果具有数据的投票成员停机或无法联系到,则永远不会得到确认。如果可能,使用一个有数据的投票成员,而不是仲裁者。

例如,考虑:

有3个投票成员的副本集,初级-次级-次级(P-S-S):

  • 所有投票成员的多数票是2票。
  • 所有有数据的投票成员的数目是3。

计算出的多数是2,最小是2和3。写必须传播到主服务器和一个次服务器,以向客户端确认写关系“大多数”。

有3个投票成员的副本集,初级仲裁者(P-S-A)

  • 所有投票成员的多数票是2票。
  • 所有有数据的投票成员的数目是2。

计算出的多数是2,最小是2和2。由于写操作只能应用于包含数据的成员,所以写操作必须传播到主节点和次节点,以向客户端确认写关注点“大多数”。

提示
避免使用与(P-S-A)或其他拓扑有关的“多数”写操作,因为这些拓扑要求所有具有数据的投票成员都可用来确认写操作。希望使用“多数”写关注点的持久性保证的客户应该部署一个不需要所有数据支持的投票成员可用的拓扑(例如P-S-S)。

Mongodb关于读取的问题(Read Concern)和Write Concern相关推荐

  1. mongodb官网文档阅读笔记:write concern

    write concern保证了mongodb写操作的级别,不同的write concern设置相应了不同级别的写操作.设置的级别越高.那么写操作的性能的持久化做得越好,可是写性能也就越差. mong ...

  2. Java操作Mongodb 保存/读取java对象到/从mongodb

    从 http://central.maven.org/maven2/org/mongodb/mongo-java-driver/选择一个版本进行下载,这里选择的是3.0.0版本,具体下载以下jar包: ...

  3. mongodb中的read concern和write concern

    read concert就是在复制集模式或复制集分片的模式下指定对于查询来说什么样的数据返回 对于下面的语句可以使用readconcern选项 find command aggregate comma ...

  4. python gridfs_python 将图片存入mongodb,读取图片,gridfs模块

    导入图片 引入模块,其中gridfs模块不需要单独安装,引入了pymongo即可直接引入 from pymongo import MongoClient from gridfs import * im ...

  5. mongodb mysql读写_MySQL vs MongoDB 1000读取

    我对MongoDb感到非常兴奋,并且最近对其进行了测试.我在MySQL中有一个名为posts的表,其中大约2000万条记录仅在名为" id"的字段上建立索引. 我想将速度与Mong ...

  6. python提取pdf表格数据导出到mongodb_python读取mongoDB数据并存入本地excel表格

    from openpyxl import Workbook import pymongo # 读取mongoDB数据库相应的表,每条数据取出数个字段存入一个dict,再将所有的dict存入一个list ...

  7. mongodb 事务_MongoDB 事务 — 基础入门篇

    MongoDB 单文档原生支持原子性,也具备事务的特性,但是我们说起事务,通常是指在多文档中的实现,因此,MongoDB 在 4.0 版本支持了多文档事务,4.0 对应于复制集的多表.多行,后续又在 ...

  8. MongoDB 基础浅谈

    作者:hazenweng,腾讯 QQ 音乐后台开发工程师 MongoDB 作为一款优秀的基于分布式文件存储的 NoSQL 数据库,在业界有着广泛的应用.下文对 MongoDB 的一些基础概念进行简单介 ...

  9. CAP理论与MongoDB一致性、可用性的一些思考

    大约在五六年前,第一次接触到了当时已经是hot topic的NoSql.不过那个时候学的用的都是mysql,Nosql对于我而言还是新事物,并没有真正使用,只是不明觉厉.但是印象深刻的是这么一张图片( ...

最新文章

  1. C语言 · 勾股数
  2. 为什么要完成量子计算机,我们为啥要量子计算机?
  3. Object类toString()和equals()方法剖析
  4. oracle aq_通过Java 8流使用Oracle AQ
  5. 直播软件自动化测试,基于SRS-Bench工具的直播平台性能测试
  6. Spring Boot基础学习笔记23:用户自定义授权管理
  7. 品质生活在于细节 8月6日张朝阳“做饭直播”带货厨房好物
  8. list操作 rediscluster_redis3.0 cluster功能介绍
  9. 基于java WebDriver +TestNG 框架环境设置
  10. python与office结合可以干什么-震惊!当Python遇到Excel后,将开启你的认知虫洞
  11. vue 项目路由配置
  12. tx关于机器人的律师函_酷q、晨风等第三方机器人被封杀停运,余者纷纷跑路!...
  13. windows中的pagefiles.sys文件是什么?pagefiles.sys文件的调整与删除
  14. win10局域网访问其他计算机名,教你win10两台电脑怎么连接局域网
  15. 科学道德与学风-2021雨课堂答案-第7章
  16. 北京互联网创业者比上海广州加起来还多!(多图)
  17. 【愚公系列】2021年12月 VUE3-循环v-for
  18. 新标准下企业申请测绘资质相关问题与解答
  19. 初学RUST-让程序跑起来
  20. iOS开发 -- 一个被苹果下架的App,终于恢复上架

热门文章

  1. SpringBoot整合阿里云OSS,传入文件为MultipartFile格式文件
  2. The Codeless Code: Case 5 Void(void本质是什么)
  3. Java 递归查询部门树形结构数据
  4. 李开复写给中国大学生的第三封信
  5. linux-I2C驱动(4)--编写驱动代码
  6. 架构师的 36 项修炼1 开篇词:7分钟Get技术人进阶技巧
  7. 辛辛苦苦学C语言究竟有什么用?
  8. 开源社区Github在2022年06月09日公测了三个新的成就徽章
  9. matlab导入示波器multisim,Multisim中示波器的使用方法
  10. marvell yukon 88e8056驱动