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 只按网络距离挑节点,不看负载,选中的可能是当前压力最大的那台从节点。