← 返回题目列表

MongoDB Read Concern、Write Concern 和 Read Preference 有什么区别?

高频 困难 第 18 / 31 题 更新于 2026/07/28
MongoDBRead ConcernWrite ConcernRead Preference一致性

简化版

Write Concern 控制写入要被多少节点确认才算成功;Read Concern 控制读取数据的一致性级别;Read Preference 控制读请求发往 primary 还是 secondary。简单说,Write Concern 管写得稳不稳,Read Concern 管读到的数据保证到什么程度,Read Preference 管从哪里读。

详细版

三者区别:

概念控制对象典型问题
Write Concern写入确认级别写入是否已被多数节点确认
Read Concern读取一致性级别读到的数据是否满足某种可见性保证
Read Preference读路由位置从 primary 读还是 secondary 读

例如:

  • writeConcern: { w: "majority" }:多数节点确认后写成功;
  • readConcern: "majority":读取已被多数节点确认的数据;
  • readPreference: "secondary":优先从 secondary 读取。

这三个配置共同影响一致性、延迟、可用性和读写压力分布。

完整版教学

一、为什么 MongoDB 要拆成三个概念

在复制集里,数据可能处于不同状态:

  • primary 已经写入;
  • secondary 还没复制;
  • 多数节点已经确认;
  • 某个节点网络延迟;
  • 读请求可能发往不同节点。

所以 MongoDB 把写入确认、读取可见性、读取路由拆成三个配置,让应用按业务选择。

二、Write Concern 管写入确认

Write Concern 决定写操作要被多少节点确认。

例如:

db.orders.insertOne(
  { orderNo: "O1001" },
  { writeConcern: { w: "majority" } }
)

majority 表示多数投票节点确认后返回成功。这样即使 primary 很快故障,新主也更可能包含这次写入。

更强的写关注通常更安全,但延迟更高。

三、Read Preference 管从哪里读

Read Preference 决定读请求路由到哪里:

  • primary;
  • primaryPreferred;
  • secondary;
  • secondaryPreferred;
  • nearest。

从 primary 读通常更容易读到最新数据;从 secondary 读可以分担压力、就近读取,但可能读到落后数据。

如果业务是订单支付结果查询,通常更偏向 primary;如果是报表或低一致性列表,可以考虑 secondary。

四、Read Concern 管读的一致性级别

Read Concern 控制读操作看到的数据保证。例如 majority 读关注会读取已被多数节点确认的数据。

它和 read preference 不是一回事。你可以从 secondary 读,但仍然要考虑这个 secondary 上数据是否满足所需读关注。

事务中还会涉及 snapshot 等更强语义。

五、三者如何组合思考

假设业务写订单后马上查询订单状态:

  • 写入用低 write concern,可能故障后丢失;
  • 查询读 secondary,可能复制延迟读不到;
  • read concern 太弱,可能读到不符合预期的数据。

如果这是核心交易链路,就要选择更强写入确认和更合理读路径。如果只是浏览统计,可以牺牲一点新鲜度换性能。

六、用业务场景组合三者

这三个配置要一起看,不能孤立背概念。比如交易订单通常希望写入至少多数确认,读取走 primary 或满足 majority 语义;报表列表可以读 secondary,接受短暂延迟;本地开发或低价值日志可以降低写确认换吞吐。

场景Write ConcernRead ConcernRead Preference
支付订单majoritymajority 或事务语义primary
普通内容浏览默认或业务可接受级别默认secondaryPreferred 可考虑
实时风控判断偏强偏强优先 primary
离线统计可放宽可放宽secondary 或分析副本

举例:写入用 w:1 后 primary 立刻故障,如果该写入尚未复制到多数节点,新 primary 可能没有这条数据;随后读 secondary 更可能看不到。这就是写确认、读保证和读位置共同决定一致性的原因。

七、常见误区与追问

Write Concern: 写成功要几个节点确认?
Read Concern: 读到的数据有什么一致性保证?
Read Preference: 读请求发到哪个节点?

记忆钩子:Write Concern 管“写稳不稳”,Read Concern 管“读的保证”,Read Preference 管“读去哪儿”。

  • 误区:Read Preference 等于 Read Concern。 前者决定读哪个节点,后者决定读取数据的一致性语义,二者不是一回事。
  • 误区:读 secondary 一定能分担压力且没有代价。 secondary 可能落后 primary,强一致读和写后读不能随便走 secondary。
  • 误区:w: majority 就保证所有节点都有数据。 majority 只要求多数投票节点确认,不代表所有 secondary 都已同步。
  • 追问:为什么强写确认会增加延迟? 写入要等待更多节点确认,网络、磁盘和复制延迟都会进入响应时间。
  • 追问:写后读怎么配置更稳? 核心链路通常用较强 write concern,并从 primary 读或使用满足业务一致性要求的 read concern。
  • 追问:什么时候可以放宽这些配置? 低价值日志、可重建数据、允许短暂旧数据的列表和报表,可以用性能和可用性换一致性。

八、加强记忆

MongoDB 一致性相关配置记成三句话:Write Concern 问“写到几个节点才算成功”,Read Concern 问“读到的数据有什么保证”,Read Preference 问“去哪个节点读”。强一致链路保守配置,低风险读场景可以换取性能和可用性。