写关注决定确认强度
writeConcern 回答一个问题:写入返回成功时,数据到底落到了几个节点、有没有落盘。w:1 表示主节点确认即返回,最快但主节点故障时可能丢最近写入;w:"majority" 要多数节点确认,安全性高但延迟更大;j:true 要求日志落盘。写入确认强度与业务容忍度要匹配,通常由默认值统一设定,个别敏感集合单独加固。
基本信息
| w | 0 不等待确认 / 1 主节点确认 / majority 多数节点确认 / 数字为指定节点数 |
|---|---|
| j | true 表示等待日志落盘后再确认 |
| wtimeout | 等待确认的超时毫秒数,仅对 w>1 有意义 |
| 默认值 | 可在副本集配置的 settings.getLastErrorDefaults 中设定全局默认 |
| 按操作覆盖 | insertOne/updateMany 等操作的选项里可单独指定 |
| 与读一致性 | 需要「写后立刻读到」时可结合多数派写与因果一致的会话 |
典型使用场景
- 日志与埋点:容忍少量丢失,用较低的 w 换取写入吞吐
- 订单与资金:用 majority 加日志落盘,确保确认即持久
- 跨机房部署:评估多数派落点位置,避免写延迟被网络往返放大
- 批量导入:临时降低确认强度提升速度,导入后再校验数据
- 写后立即读:配合会话与读关注,保证读到自己的写入
示例
示例
// 单条写入:多数派确认并等待日志落盘,适合对数据安全性敏感的场景
db.orders.insertOne(
{ sku: "C-1", qty: 1 },
{ writeConcern: { w: "majority", j: true, wtimeout: 5000 } }
)
// 批量写入:确认强度同样可以在操作级覆盖
db.orders.bulkWrite(ops, { ordered: false, writeConcern: { w: "majority" } })
// 查看副本集当前的默认写关注配置
rs.conf().settings.getLastErrorDefaults
// wtimeout 触发后返回错误,但写入可能已经成功:重试前先按业务主键确认状态w 取值读法
| 取值 | 确认范围 | 适用与代价 |
|---|---|---|
| 0 | 不等待确认 | 吞吐最高,出错无反馈,仅适合可容忍丢失的数据 |
| 1 | 主节点内存确认 | 默认级别,主节点故障存在丢最近写入的可能 |
| majority | 多数投票成员确认 | 安全性与延迟的平衡点,跨机房部署时延迟上升 |
| 指定数字 | 指定数量节点确认 | 按拓扑定制,节点数变化时需要同步调整 |
| 自定义标签 | 按标签定义的节点集合确认 | 适合表达「写入指定机房」这类业务语义 |
确认强度与延迟直接相关:跨数据中心的多数派写入要等网络往返,评估拓扑时把机房布局与超时设置一起考虑,而不是只调大 w。
wtimeout 超时返回错误不代表写入失败:确认还没到不代表操作没执行,直接重试可能产生重复数据,需要幂等设计。