对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

配置增删改查操作

在本指南中,您可以学习;了解如何配置写关注(write concern)、读关注(read concern)和读取偏好(read preference)选项,以修改Scala驾驶员在副本集上运行写入操作的方式。

您可以在以下级别设置写关注、读关注和读取偏好选项:

  • 客户端,为所有操作执行设置默认值,除非被覆盖

  • 事务

  • Database

  • Collection

此列表还指示了选项设置的优先级递增顺序。示例,如果为ACID 事务设立读关注(read concern),它将覆盖从客户端继承的读关注(read concern)设置。

写关注、读关注(read concern)和读取偏好(read preference)选项允许您自定义副本集中数据的因果一致性和可用性。 要查看这些选项的完整列表,请参阅MongoDB Server手册中的以下指南:

您可以通过设置读取偏好来控制驱动程序如何在副本集成员之间路由读取操作。您还可以通过设置读关注和写关注来控制驱动程序在副本集上等待读取和写入操作确认的方式。

以下部分介绍如何在各个级别配置这些读取和写入设置。

此示例演示如何通过将 MongoClientSettings实例传递给构造函数来设立MongoClient实例的读取偏好(read preference)、读关注(read concern)和写关注(write concern)。该代码配置以下设置:

  • secondary 读取偏好(read preference):读取操作从从节点(secondary node from replica set)副本集成员检索数据。

  • LOCAL 读关注(read concern):读取操作会返回实例的最新数据,但不保证该数据已写入大多数副本集成员。

  • W2 写关注(write concern):主节点 (primary node in the replica set)副本集成员和一个从节点(secondary node from replica set)成员必须确认写入操作。

val mongoClient = MongoClient(MongoClientSettings.builder()
.applyConnectionString(ConnectionString("mongodb://localhost:27017/"))
.readPreference(ReadPreference.secondary())
.readConcern(ReadConcern.LOCAL)
.writeConcern(WriteConcern.W2)
.build())

或者,您可以在连接 URI 中指定读取和写入设置,该 URI 作为参数传递给MongoClient构造函数:

val uriClient = MongoClient("mongodb://localhost:27017/?readPreference=secondary&w=2&readConcernLevel=local")

此示例演示如何通过将 TransactionOptions实例传递给 startTransaction() 方法来设立ACID 事务的读取偏好(read preference)、读关注(read concern)和写关注(write concern)。事务在会话中运行,会话是要按顺序运行的相关读取或写入操作的分组。

提示

要学习;了解有关会话的更多信息,请参阅MongoDB Server手册中的服务器会话。

该示例配置了以下设置:

  • primary 读取偏好(read preference):读取操作从主节点 (primary node in the replica set)副本集成员检索数据。

  • MAJORITY 读关注(read concern):读取操作返回实例已写入大多数副本集成员的最新数据。

  • W1 写关注(write concern):主节点 (primary node in the replica set)副本集成员必须确认写入操作。

val clientSessionFuture = mongoClient.startSession().toFuture()
val clientSession = Await.result(clientSessionFuture, Duration(10, TimeUnit.SECONDS))
val tOptions: TransactionOptions = TransactionOptions.builder()
.readPreference(ReadPreference.primary())
.readConcern(ReadConcern.MAJORITY)
.writeConcern(WriteConcern.W1)
.build()
clientSession.startTransaction(tOptions)

此示例展示了如何通过将 setter 方法链接到 getDatabase() 方法来设立名为 test_database 的数据库的读取偏好(read preference)、读关注(read concern)和写关注(write concern)。 该代码配置以下设置:

  • primaryPreferred 读取偏好(read preference):读取操作从主节点 (primary node in the replica set)副本集成员检索数据,如果主节点 (primary node in the replica set)不可用,则从从节点(secondary node from replica set)成员检索数据。

  • AVAILABLE 读关注(read concern):读取操作会返回实例的最新数据,但不保证该数据已写入大多数副本集成员。

  • MAJORITY 写关注(write concern):所有副本集成员中的大多数必须确认写入操作。

val database = mongoClient.getDatabase("test_database")
.withReadPreference(ReadPreference.primaryPreferred())
.withReadConcern(ReadConcern.AVAILABLE)
.withWriteConcern(WriteConcern.MAJORITY)

此示例展示了如何通过将 setter 方法链接到 getCollection() 方法来设立名为 test_collection 的集合的读取偏好(read preference)、读关注(read concern)和写关注(write concern)。 该代码配置以下设置:

  • secondaryPreferred 读取偏好(read preference):读取操作从从节点(secondary node from replica set)副本集拟节点检索数据,如果没有可用的从节点(secondary node from replica set)节点,则从主节点 (primary node in the replica set)节点检索数据。

  • AVAILABLE 读关注(read concern):读取操作会返回实例的最新数据,但不保证该数据已写入大多数副本集成员。

  • UNACKNOWLEDGED 写关注(write concern):副本设立成员不需要确认写入操作。

val collection = database.getCollection("test_collection")
.withReadPreference(ReadPreference.secondaryPreferred())
.withReadConcern(ReadConcern.AVAILABLE)
.withWriteConcern(WriteConcern.UNACKNOWLEDGED)

以下部分介绍了进一步自定义Scala驾驶员程序如何路由读取操作的方法。

您可以在连接到分片集群时指定读取偏好(read preference)。MongoDB使用分片按键范围划分数据集,并将数据分布到多个数据库实例。分片集群(或分片的部署中的节点设立)包括以下组件:

  • 分片:包含分片的数据子集的副本副本集。

  • Mongos:一种查询路由器,在应用程序和分片集群之间提供接口。

  • 配置服务器:存储集群配置设置和元数据的服务器。

提示

要学习;了解有关分片的集群的更多信息,请参阅MongoDB Server手册中的分片

从副本集分片读取时,mongos 会应用您指定的读取偏好(read preference)。对于每个操作,都会重新评估读取偏好(read preference)。

以下示例展示了如何连接到分片集群并在连接字符串中指定 secondary读取偏好(read preference):

val mongosClient = MongoClient("mongodb://user:password@mongos1.example.com,mongos2.example.com/?readPreference=secondary")

在MongoDB Server中,您可以根据您选择的任何条件将键值标签应用副本集成员。然后,您可以使用这些标签来定位一个或多个成员以执行读取操作。

默认情况下,Scala 驱动程序在选择要读取的节点时会忽略标签。要指示 Scala 驱动程序优先选择某些标签,请将标签作为列表传递给您的读取偏好 setter 方法。

假设您连接到一个副本集,其中包含托管在美国多个数据中心的节点。您希望驱动程序优先按以下顺序从从节点副本集成员中读取:

  1. 来自 纽约数据中心 的节点,标记为 ("dc", "ny")

  2. 来自旧金山数据中心的节点,标记为 ("dc", "sf")

  3. 任何从从节点(secondary node from replica set)

此代码示例会将表示前面副本集成员的标签列表传递给 ReadPreference.secondary() setter 方法。 然后,代码将读取偏好(read preference)信息传递给 withReadPreference() 方法,以在数据库上设立读取顺序:

val tag1 = new TagSet(new Tag("dc", "ny"))
val tag2 = new TagSet(new Tag("dc", "sf"))
val tag3 = new TagSet()
val readPreference = ReadPreference.secondary(List(tag1, tag2, tag3).asJava)
val database = mongoClient.getDatabase("test_database")
.withReadPreference(readPreference)

连接到分片集群或副本集时, Scala驾驶员使用负载均衡来处理读取和写入请求。负载均衡允许驾驶员将这些请求分发到多台服务器,从而避免任何一台服务器不堪重负,确保最佳性能。

连接到分片集群时, Scala驾驶员会计算网络往返时间最短的实例,从而确定最接近的mongos 实例。然后,驾驶员通过将此mongos 实例的平均往返时间与 localThresholdMS 值相加来确定延迟窗口。驾驶员在延迟窗口内的最多两个随机mongos 实例之间对请求进行负载均衡。对于每个请求,驾驶员会通过确定其operationCount 值来选择具有较低操作负载的服务器。

连接到副本集时, Scala驾驶员首先根据读取偏好(read preference)副本集成员。然后,驾驶员执行与上一段所述相同的进程。计算延迟窗口后,驾驶员最多选择两个处于该窗口内的随机副本集节点,并选择具有较低 operationCount 值的节点来接收请求。

提示

要学习;了解有关负载均衡的更多信息,请参阅MongoDB Server手册中的分片集群负载均衡器

连接到副本集时,并使用非主节点 (primary node in the replica set) 读取偏好(read preference),驱动程序会从延迟窗口内最近的符合条件的副本集读取。连接到分片集群时,驱动程序会从延迟窗口内所有可访问的 mongos 实例中进行选择。要了解读取偏好模式,请参阅 读取偏好(read preference)。

默认情况下,驱动程序仅使用网络探测(ping)时间在距离最近的符合条件的服务器 15 毫秒以内的服务器。

例如,假设您的副本集有五个节点,而最近的节点的网络探测(ping)时间为 5 毫秒。使用默认 localThresholdMS (15 毫秒),只有网络探测(ping)时间小于或等于 20 毫秒的节点才在延迟窗口内,如下表所示:

主机
类型
网络探测(ping)时间
延迟窗口内

host1

主节点

5 毫秒

host2

从节点

9 毫秒

host3

从节点

13 毫秒

host4

从节点

24 毫秒

No

host5

从节点

42 毫秒

No

要调整延迟窗口,请在 MongoClientSettings 实例中设置 localThreshold 选项,或在连接 URI 中设置 localThresholdMS 选项。

以下示例连接到副本集并指定 35 毫秒的本地阈值。选择 MongoClientSettingsConnection URI标签页,查看每种方法对应的代码:

val client = MongoClient(MongoClientSettings.builder()
.applyConnectionString(ConnectionString("mongodb://localhost:27017/"))
.applyToClusterSettings(builder => builder
.localThreshold(35, TimeUnit.MILLISECONDS)
)
.build())
val connectionString = "mongodb://localhost:27017/?replicaSet=repl0&localThresholdMS=35"
val client = MongoClient(connectionString)

在前面的示例中, Scala驱动程序在最近节点的网络探测(ping)时间后的 35 毫秒内在匹配节点之间分发读取。

如果某些写入操作由于网络或服务器错误而失败,Scala驾驶员会自动重试一次。

您可以通过在 MongoClientSettings实例中将 retryReadsretryWrites 选项设置为 false 来显式禁用可重试读取或可重试写入。您还可以在连接 URI 中设立retryReadsretryWrites 选项。

以下示例将可重试读取和可重试写入均设置为 false。选择 MongoClientSettingsConnection URI标签页,查看每种方法对应的代码:

val retryClient = MongoClient(MongoClientSettings.builder()
.applyConnectionString(ConnectionString("mongodb://localhost:27017/"))
.retryReads(false)
.retryWrites(false)
.build())
val retryUriClient = MongoClient("mongodb://localhost:27017/?retryReads=false&retryWrites=false")

要学习;了解有关支持的可重试读取操作的更多信息,请参阅MongoDB Server手册中的可重试读取。要学习;了解有关支持的可重试写入操作的更多信息,请参阅MongoDB Server手册中的可重试写入。

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: