进入MongoDB中文手册(4.2版本)目录
对于与多文档事务无关的读取操作,读策略"majority" 确保大多数副本集成员已确认读取的数据(即,读取的文档是持久化的并且保证不会回滚)。
对于多文档事务中的操作,仅当事务以 写策略“majority”提交时,读策略"majority"才提供其保证。否则, 读策略"majority"不能保证事务中读取的数据。
无论读策略级别如何,节点上的最新数据都可能不是系统中最新版本的数据。
1 性能
每个副本集成员在内存中维护多数提交点(majority-commit point)的数据视图;多数提交点是由主节点计算的。为了满足读策略"majority",该节点从该视图返回数据,并且性能成本与其他读策略相当。
2 可用性
读策略"majority"可用于有或没有因果关系一致的会话和事务。
部署具有三名成员的主次仲裁器(PSA)架构时可以禁用读策略"majority"。但是,这对变更流(仅在MongoDB 4.0和更早版本中)和分片群集上的事务有影响。有关更多信息,请参见禁用多数读策略。
3 示例
考虑以下写操作的时间轴,将Write0写入副本集的三个成员:
注意
为了简化,该示例假定:
* 写入Write0之前的所有写入已成功复制到所有成员;
* Writeprev在Write0之前写入;
*Write0之后不会有其他写入发生。
时间 | 事件 | 最近的写操作 (Most Recent Write) | 最近的w: “majority”写操作 (Most Recent w: “majority” write) |
---|---|---|---|
t0 | 主节点写Write0 | 主节点:Write0 次节点1:Writeprev 次节点2:Writeprev | 主节点:Writeprev 次节点1:Writeprev 次节点2:Writeprev |
t1 | 次节点1写Write0 | 主节点:Write0 次节点1:Write0 次节点2:Writeprev | 主节点:Writeprev 次节点1:Writeprev 次节点2:Writeprev |
t2 | 次节点2写Write0 | 主节点:Write0 次节点1:Write0 次节点2:Write0 | 主节点:Writeprev 次节点1:Writeprev 次节点2:Writeprev |
t3 | 主节点知道成功复制到了次节点1,并向客户端发送确认 | 主节点:Write0 次节点1:Write0 次节点2:Write0 | 主节点:Write0 次节点1:Writeprev 次节点2:Writeprev |
t4 | 主节点知道成功复制到了次节点2 | 主节点:Write0 次节点1:Write0 次节点2:Write0 | 主节点:Write0 次节点1:Writeprev 次节点2:Writeprev |
t5 | 次节点1收到通知(通过常规复制机制),并更新最近的w: “majority”写入的快照 | 主节点:Write0 次节点1:Write0 次节点2:Write0 | 主节点:Write0 次节点1:Write0 次节点2:Writeprev |
t6 | 次节点2收到通知(通过常规复制机制),并更新最近的w: “majority”写入的快照 | 主节点:Write0 次节点1:Write0 次节点2:Write0 | 主节点:Write0 次节点1:Write0 次节点2:Write0 |
然后,下表总结了具有读策略"local"的读操作在时间T看到的数据状态。
读取目标 | 时间T | 数据状态 |
---|---|---|
主节点 | 在t3之后 | 数据反映为Write0 |
次节点1 | 在t5之前 | 数据反映为Writeprev |
次节点1 | 在t5之后 | 数据反映为Write0 |
次节点2 | 在t6之前 | 数据反映为Writeprev |
次节点2 | 在t6之后 | 数据反映为Write0 |
4 存储引擎的支持
策略"majority"适用于WiredTiger存储引擎。
提示
serverStatus命令返回storageEngine.supportsCommittedReads字段,该字段表示存储引擎是否支持读策略"majority"。
5 读策略"majority"和事务
提示
您可以在事务级别上而不是在单个操作级别上设置读策略。要设置事务的读策略,请参见事务和读策略。
对于多文档事务中的操作,仅当事务以写策略"majority"提交时,读策略才提供其保证。否则, 读策略"majority"不能保证事务中读取的数据。
5 读策略"majority"和聚合
从MongoDB 4.2开始,您可以为包含 o u t 阶 段 的 聚 合 指 定 读 策 略 " m a j o r i t y " 。 在 M o n g o D B 4.0 和 更 早 版 本 中 , 您 不 能 包 括 将 读 策 略 " m a j o r i t y " 用 于 包 含 out阶段的聚合指定读策略"majority"。 在MongoDB 4.0和更早版本中,您不能包括将读策略"majority"用于包含 out阶段的聚合指定读策略"majority"。在MongoDB4.0和更早版本中,您不能包括将读策略"majority"用于包含out 阶段的聚合。
5 读自己写入的数据
在版本3.6中更改。
从MongoDB 3.6开始,如果写请求确认,则可以使用因果一致的会话来读取自己的写入。
在MongoDB 3.6之前,您必须发出具有写策略{ w: “majority” }的写入操作, 然后 对读取操作使用"majority"或"linearizable"的读策略,以确保单个线程可以读取自己写入的数据。
6 禁用读策略Majority
适用于三成员的主次仲裁器体系结构(3-Member Primary-Secondary-Arbiter Architecture)。
如果您拥有一个主次仲裁器(PSA)体系结构的三成员副本集或三成员PSA分片的分片群集,则可以禁用读策略"majority"。
提示
如果您使用的是三成员PSA以外的其他部署,则无需禁用读策略"majority"。
使用三成员PSA架构,如果任何数据承载节点发生故障,则缓存压力将增加。为防止PSA架构的部署不正常运行导致的存储缓存压力,您可以通过以下方式禁用读策略:
- 命令行选项–enableMajorityReadConcern设置为false;
- 配置文件设置replication.enableMajorityReadConcern为false。
要检查是否已禁用读策略"majority",您可以在mongod实例上运行db.serverStatus()并检查storageEngine.supportsCommittedReads字段。如果为false,则禁用读策略"majority"。
重要
通常,除非必要,请避免禁用读策略"majority"。但是,如果您有一个具有主次仲裁器(PSA)体系结构的三成员副本集,或者具有一个三成员PSA分片的分片群集,请禁用该功能以防止PSA架构的部署不正常运行导致的存储缓存压力。
更改流(Change Streams)
禁用读策略"majority"会禁用对MongoDB 4.0及更早版本的变更流的支持。对于MongoDB 4.2+,禁用读策略"majority"不会影响更改流的可用性。
事务
禁用读策略"majority"会影响对分片群集上事务的支持 。特别是:
- 如果事务涉及已禁用读策略"majority"的分片,则该事务不能使用读策略"snapshot"。
- 如果事务的任何读或写操作涉及了禁用读策略"majority"的分片,写入多个分片的事务会报错。
但是,它不影响副本集上的事务。对于副本集上的事务,即使禁用了读策略"majority",也可以为多文档事务指定读策略"majority"(或"snapshot" 或"local")。
进入MongoDB中文手册(4.2版本)目录