0Pricing
MongoDB Academy · 课时

读取偏好:分配读取负载

您将配置 primary、primaryPreferred、secondary、nearest 及带标签的读取偏好,以便在副本集之间路由读取请求。

读取偏好:分配读取负载 是 CoddyKit 上的免费 MongoDB Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 MongoDB Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 MongoDB Academy 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

What Is a Read Preference?

A read preference controls which replica set member the driver sends read operations to. By default, all reads go to the primary to ensure you always see the latest data. However, redirecting reads to secondaries can reduce load on the primary and bring reads geographically closer to users — at the cost of potentially reading slightly stale data.

primary: Always Read From Primary

primary (the default) routes every read to the primary. This guarantees strong consistency — you will always read your own writes and see the most up-to-date data. The downside is that the primary handles all read and write traffic. Use this mode whenever stale data would be unacceptable, such as in financial applications or user-facing dashboards.

// Explicit primary read preference (this is the default)
const col = db.collection('accounts', {
  readPreference: 'primary'
})
await col.findOne({ _id: userId })

primaryPreferred: Fallback to Secondary

primaryPreferred reads from the primary when it is available but falls back to a secondary if the primary is unreachable. This provides a balance: you normally get fresh data, but the application degrades gracefully during primary elections. Be aware that during the fallback, you may read data that is a few seconds behind.

const col = db.collection('products', {
  readPreference: 'primaryPreferred'
})
await col.find({}).toArray()

secondary: Read Only From Secondaries

secondary sends all reads to available secondaries, never touching the primary. This is ideal for analytics queries, batch jobs, or reporting that can tolerate eventual consistency. It offloads significant read pressure from the primary. If no secondary is available, the operation fails — it will NOT fall back to the primary.

// Route analytics query to secondary
const col = db.collection('events', {
  readPreference: 'secondary'
})
const count = await col.countDocuments({ type: 'click' })

secondaryPreferred: Secondary With Fallback

secondaryPreferred prefers secondaries but falls back to the primary if no secondary is available. This is the most commonly used non-default mode — it spreads read load across secondaries under normal conditions while remaining available when a secondary goes down. The caveat is the same as secondary: reads may be slightly stale.

const col = db.collection('catalog', {
  readPreference: 'secondaryPreferred'
})
await col.find({ category: 'books' }).toArray()

nearest: Lowest Network Latency

nearest sends reads to the member with the lowest measured network round-trip time, regardless of whether it is primary or secondary. This is perfect for globally distributed applications where users in different regions should read from the closest data center. Note that different users may read from different members, so they may temporarily see different data states.

const col = db.collection('content', {
  readPreference: 'nearest'
})
await col.findOne({ slug: 'hello-world' })

Tag Sets: Targeting Specific Members

Tag sets let you label replica set members (e.g., { region: 'us-east' }, { purpose: 'analytics' }) and then write read preferences that target only matching members. This enables sophisticated routing: send application reads to the nearest region and analytics queries to a dedicated secondary, all within the same replica set.

// Tag a member in replica set config
let cfg = rs.conf()
cfg.members[2].tags = { region: 'eu-west', purpose: 'analytics' }
rs.reconfig(cfg)

// Read from eu-west analytics member
const col = db.collection('reports', {
  readPreference: new ReadPreference('secondary', [{ region: 'eu-west' }])
})

Stale Reads and Replication Lag

When reading from secondaries, you may encounter stale reads — the secondary hasn't replicated the latest writes from the primary yet. The staleness depends on replication lag. MongoDB 3.6 introduced maxStalenessSeconds: the driver refuses to use a secondary lagging more than the specified number of seconds, preventing very stale reads.

// Reject secondaries more than 90 seconds behind
const col = db.collection('products', {
  readPreference: new ReadPreference(
    'secondaryPreferred',
    [],
    { maxStalenessSeconds: 90 }
  )
})

Read Preference in the Connection String

You can set the default read preference for all operations in the connection string using the readPreference parameter. This is the easiest way to configure the default without changing every call site. Individual operations can still override it by passing a readPreference option explicitly.

// Connection string with secondaryPreferred default
const uri = 'mongodb+srv://host/db?readPreference=secondaryPreferred&maxStalenessSeconds=120'
const client = new MongoClient(uri)

Read Preference and Transactions

Multi-document transactions must always use primary read preference. Operations inside a transaction that specify a different read preference will throw an error. This ensures that all reads within the same transaction see a consistent snapshot as of the transaction's start time on the primary.

// Inside a transaction, reads always go to primary
const session = client.startSession()
await session.withTransaction(async () => {
  // This implicitly uses primary read preference
  const order = await db.orders.findOne({ _id: orderId }, { session })
  await db.inventory.updateOne({ sku: order.sku }, { $inc: { qty: -1 } }, { session })
})

Choosing Read Preference in Practice

Use this guide: Real-time user data (cart, profile, notifications) → primary. Product catalog, content → secondaryPreferred. Reports and analytics → secondary with a dedicated analytics member. Global CDN-like reads → nearest. Always measure replication lag before routing critical reads to secondaries.

Quick Check

Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.

Lesson Recap

In this lesson you learned: read preferences control which replica set member handles read operations, secondary and secondaryPreferred offload read traffic at the cost of eventual consistency, and nearest minimises latency in geo-distributed deployments. Next up we explore sharding — MongoDB's strategy for scaling beyond a single replica set.

常见问题解答

「读取偏好:分配读取负载」课时是免费的吗?

是的 — 「读取偏好:分配读取负载」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 MongoDB Academy 课程的其余内容,请升级到 CoddyKit PRO。 MongoDB Academy 课程共包含 4 节课。

「读取偏好:分配读取负载」这节课中我会学到什么?

您将配置 primary、primaryPreferred、secondary、nearest 及带标签的读取偏好,以便在副本集之间路由读取请求。 你通过在浏览器中直接运行的动手代码来练习 MongoDB Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 MongoDB Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 MongoDB Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「读取偏好:分配读取负载」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 MongoDB Academy 课中编写并运行代码吗?

能。每节 MongoDB Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 副本集成员:主节点、从节点和仲裁者
  2. 选举和自动故障转移
  3. 写关注和已确认的持久性
  4. 读取偏好:分配读取负载
← 返回 MongoDB Academy