进入MongoDB中文手册(4.2版本)目录
写策略描述了MongoDB的写操作对单机mongod或副本集或分片群集的请求确认级别。在分片群集中,mongos实例会将写策略传递给分片。
- 注意
- 对于多文档事务,可以在事务级别而不是在单个操作级别设置写策略。不要为事务中的各个写操作明确设置写策略。
1 写确认规范
写策略可以包括以下字段:
{ w: <value>, j: <boolean>, wtimeout: <number> }
- 使用w选项来请求确认写入操作已传播到指定数量的mongod 实例或具有指定标签的mongod实例;
- 使用j选项来请求确认写操作已被写入到磁盘上的日志;
- wtimeout选项来指定一个时间限制,以防止无限期阻塞写操作。
1.1 w选项
w选项请求确认写操作已传播到指定数量的mongod实例或具有指定标签的mongod实例。
使用该w选项,可以使用以下w: 写策略:
值 | 描述 |
---|---|
<number> | 请求确认写入操作已传播到指定数量的mongod实例。例如: w: 1 请求确认写入操作已传播到单机mongod或副本集中的主节点。w: 1是MongoDB的默认写策略。 w: 1 请求不确认写操作。但是,w: 0可能会将有关socket异常和网络错误的信息返回给应用程序。 如果指定w: 0但包括j:true,则 j:true优先从单机mongod或副本集的主节点请求确认。 w大于1则需要主节点和众多其他具有数据承载能力的次节点进行确认,以符合指定的写策略。例如,考虑一个没有仲裁者( arbiters)的3成员副本集。指定w: 2将需要主节点和其中一个次节点确认。指定w: 3将需要主节点和2个次节点确认。 注意: Hidden, delayed和priority 0 成员可以确认w: <number>写操作。 延迟的次节点可以在slaveDelay配置返回之后返回写确认。 有关mongod实例何时确认写入的信息,请参见确认行为(Acknowledgment Behavior)。 |
<majority> | 请求确认写操作已传播到所计算的承载数据的投票成员的大多数(即主节点和members[n].votes大于0的次节点)。 例如,考虑一个具有3个投票成员的副本集,即Primary-Secondary-Secondary(PSS)。对于此副本集, 计算出的多数为2,并且写入必须传播到主节点和一个次节点,以向客户端确认写入策略。 注意: Hidden, delayed和priority 0 成员,其members[n].votes大于0 可以确认"majority"写操作。 延迟的次节点可以在slaveDelay配置返回之后返回写确认。 在写操作返回有w: "majority"确认消息给客户端之后,客户端可以使用读策略"majority"读取该写操作的结果 。 有关mongod实例何时确认写入的信息,请参见确认行为(Acknowledgment Behavior)。 |
<自定义写确认名称> | 请求确认写操作已传播到,满足settings.getLastErrorModes中自定义写确认的被标记(tagged)的成员 。 有关示例,请参阅“ 自定义多数据中心写策略(Custom Multi-Datacenter Write Concerns)”。 有关mongod实例何时确认写入的信息,请参见确认行为(Acknowledgment Behavior)。 |
也可以看看: 副本集协议版本(Replica Set Protocol Version)。
1.2 j选项
j选项要求MongoDB确认已将写操作写入磁盘日志中。
值 | 描述 |
---|---|
j | 如果为j: true,则请求确认中指定w:的mongod实例已写入磁盘日志中。j: true本身并不能保证写操作不会因副本集主节点故障转移而回滚。 在版本3.2中进行了更改:使用j: true时,MongoDB仅在请求数量的成员(包括主节点)写入日志后才返回。不管w:写策略如何,之前副本集中写策略j: true只要求主节点写到日志。 |
注意
* 向一个mongod实例指定j: true的写策略,如果该mongod实例没有日志则会产生错误。
* 如果启用日志功能,则w: "majority"可能意味着j: true。副本集配置writeConcernMajorityJournalDefault的设置决定这个行为。有关详细信息,请参见确认行为。
1.3 wtimeout
此选项指定写策略的时间限制(以毫秒为单位)。wtimeout仅适用于w大于1的值 。
即使要求的写操作最终会成功,写操作在超出指定的wtimeout限制也会返回错误。当这些写入操作返回时,MongoDB不会撤消在写策略超出wtimeout的时间限制之前成功执行的数据修改内容。
如果您未指定wtimeout选项并且无法实现写策略级别,则写操作将无限期阻塞。指定wtimeout值为0等同于不带wtimeout选项的写策略。
2 确认行为
该w选项和j选项确定何时mongod实例确认写操作。
2.1 单机(Standalone)
一个单机mongod应用程序在执行了内存写入之后或写入磁盘日志后会确认写操作。下表列出了单机的确认行为以及相关的写策略:
写策略 | 没有指定j | j:true | j:false |
---|---|---|---|
w: 1 | 内存中 | 磁盘日志 | 内存中 |
w: “majority” | 磁盘日志(如果与日志一起运行) | 磁盘日志 | 内存中 |
注意
如果writeConcernMajorityJournalDefault设置为false,MongoDB的不会在写操作确认之前等待w: "majority"写操作被写入到磁盘上的日志中。这样,在给定副本集中的大多数节点发生瞬时丢失(例如崩溃和重新启动)的情况下,majority写操作可能会回滚。
2.2 副本集(Replica Sets)
指定w的值决定了返回成功之前必须确认写入的副本集成员的数量。对于每个合格的副本集成员,j 选项决定成员是在内存中执行写操作之后还是在写入磁盘日志后确认写操作。
w: "majority"
副本集中任何承载数据的投票成员都可以对"majority"写操作的写确认有所贡献。
下表列出了成员何时可以基于j值确认写入:
j值 | 描述 |
---|---|
没有指定j | 写确认取决于writeConcernMajorityJournalDefault的值 : * 如果为true,则写确认需要将操作写入磁盘日志(j: true)。 writeConcernMajorityJournalDefault默认为 true * 如果为false,则写确认需要在内存进行写操作(j: false)中。 |
j: true | 写确认需要将操作写入磁盘日志。 |
j: false | 写确认需要在内存中进行写操作。 |
注意
如果writeConcernMajorityJournalDefault设置为false,MongoDB的不会在写操作确认之前等待w: "majority"写操作被写入到磁盘上的日志中。这样,在给定副本集中的大多数节点发生瞬时丢失(例如崩溃和重新启动)的情况下,majority写操作可能会回滚。
注意
Hidden, delayed和priority 0 成员,其members[n].votes大于0 可以确认"majority"写操作。
延迟的次节点可以在slaveDelay配置返回之后返回写确认
w: <number>
副本集的任何承载数据的成员都对w:写操作的写确认有所贡献。
下表列出了成员何时可以基于j值确认写入:
j值 | 描述 |
---|---|
没有指定j | 写确认需要在内存进行写操作(j: false)中。 |
j: true | 写确认需要将操作写入磁盘日志。 |
j: false | 写确认需要在内存中进行写操作。 |
注意
Hidden, delayed和priority 0 成员可以确认 w: <number>写操作。
延迟的次节点可以在slaveDelay配置返回之后返回写确认
2.3 写策略大多数的计算
提示
从版本4.2.1开始,rs.status()返回包含计算出的多数数字(majority number)的writeMajorityCount字段。
写策略"majority"的多数由以下值中的较小者计算得出:
- 所有投票成员(包括仲裁员)中的大多数;
- 所有带有数据的投票成员的数量。
警告
如果计算出的大多数数字等于所有承载数据的有投票权的成员的数量(例如,由3个成员组成的主次仲裁部署),则写策略 "majority"可能会超时,或者如果承载数据的有投票权的成员掉线或无法连接则永远不会收到写确认。如果可能,请使用一个承载数据的投票成员代替仲裁者。
例如:
-
副本集包含3个投票成员,主-次-次(PSS):
- 所有投票成员的大多数为2;
- 所有承载数据投票的成员人数为3。
计算得出的大多数为2,2和3的最小值。写入必须传播到主要主节点和一个次节点,以向客户端确认写策略"majority"。
-
副本集包含3个有投票权的成员,主-次-仲裁(PSA)
- 所有投票成员中大多数为2。
- 所有承载数据的投票的成员数为2。
计算得出的大多数为2,为2和2的最小值。由于该写操作只能应用于数据承载成员,因此该写操作必须传播到主节点和次节点,以向客户端确认写策略"majority"。
提示
避免将写策略"majority"与一个(PSA)或其他要求使用所有承载数据的投票成员才能确认写入的拓扑配合使用。希望使用写策略"majority"的持久性保证的客户应改用不要求所有具有数据投票权的成员都可用的拓扑(例如PSS)。