首页/数据/NoSQL 速查/读偏好 readPreference 与从节点读
MongoDB99 条

读偏好 readPreference 与从节点读

控制读请求走哪个节点:primary(默认)、primaryPreferred、secondary、secondaryPreferred、nearest;写入总是送往主节点。

NoSQL 速查数据更新于 2026-10-13

readPreference 是什么

readPreference 决定读请求发给复制集里的哪类节点:primary 只读主节点(默认值),primaryPreferred 主节点可用时读主、否则读从,secondary 只读从节点,secondaryPreferred 优先读从节点,nearest 按网络往返延迟挑选最近的可用节点。写请求始终送到主节点,不受该设置影响。从节点读可以分摊主节点压力、把统计类查询放到本地机房,代价是复制延迟带来旧读。

基本信息

取值范围primary / primaryPreferred / secondary / secondaryPreferred / nearest
会话级设置db.getMongo().setReadPref("secondaryPreferred")
游标级覆盖cursor.readPref("secondary")
附加约束maxStalenessSeconds 限制可接受的最大副本延迟
影响范围只影响读路径,写操作永远走主节点

典型使用场景

  • 多机房就近读:让各机房读本地副本,减少跨机房往返延迟
  • 报表与导出:把后台统计查询放到从节点,避免抢占线上读资源
  • 主节点故障期:primaryPreferred 让读请求在主节点不可用时自动落到从节点
  • 读扩展:读多写少的集合靠从节点横向分摊查询压力
  • 单条查询试验:用游标级 readPref 临时验证从节点读的效果

设置方式

设置方式
// 会话级:之后的查询默认按这个偏好走
db.getMongo().setReadPref("secondaryPreferred")

// 游标级:只覆盖这一条查询
db.orders.find({ status: "paid" }).readPref("secondary")

// 带最大延迟约束,超出则回到更近的节点
db.getMongo().setReadPref("nearest", maxStalenessSeconds = 90)

// 查看当前生效值
db.getMongo().getReadPref()

五档读偏好对照

取值读哪个节点适用场景
primary只读主节点强一致与读己之写场景(默认)
primaryPreferred优先主,不可用才读从主节点故障期保持读可用
secondary只读从节点明确要把读压力移出主节点
secondaryPreferred优先从,无从时读主分析查询与就近读
nearest延迟最低的节点多机房就近访问,不保证最新数据
从节点读有复制延迟,写入后立刻读可能读不到或读到旧值。「读自己所写」的场景保持默认 primary,或改用因果一致的会话读取。
maxStalenessSeconds 可以给「能接受多旧」设上限;nearest 只按网络距离挑节点,不看负载,选中的可能是当前压力最大的那台从节点。

易错点

  • 把读偏好全局改成 secondary 后,用户刚提交完就读不到自己的数据,容易被当成写入丢失
  • nearest 在多机房环境下会随网络抖动在两机房之间来回漂移,读路径的延迟分布变得不可控
  • 从节点正在做备份或大量合并时读延迟尖刺比主节点更明显,读偏好不会规避这类节点
  • 分片集群上连接串、会话、分片三个层级都能设读偏好,覆盖顺序要按官方文档核对,否则改了不生效

数据来源与参考

  • MongoDB Manual: Read Preference
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌