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

配置增删改查操作

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

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

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

  • 事务

  • Database

  • Collection

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

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

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

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

此示例演示如何通过将 MongoClientSettings实例传递给 MongoClients.create() 方法来设立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)成员必须确认写入操作。

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("<your connection string>"))
.readPreference(ReadPreference.secondary())
.readConcern(ReadConcern.LOCAL)
.writeConcern(WriteConcern.W2)
.build();
MongoClient client = MongoClients.create(settings);

或者,您可以在连接 URI 中指定读取和写入设置,该 URI 作为参数传递给 MongoClients.create() 方法:

MongoClient client = MongoClients.create(
"mongodb://<host>:<port>/?readPreference=secondary&readConcernLevel=local&w=2");

此示例演示如何通过将 TransactionOptions实例传递给 startTransaction() 方法来设立ACID 事务的读取偏好(read preference)、读关注(read concern)和写关注(write concern)。事务在 会话 中运行,会话是您打算按顺序运行的相关读取或写入操作的分组。在应用ACID 事务选项之前,请使用 startSession() 方法启动会话。

提示

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

该示例配置了以下设置:

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

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

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

ClientSession clientSession = Mono.from(client.startSession()).block();
TransactionOptions txnOptions = TransactionOptions.builder()
.readPreference(ReadPreference.primary())
.readConcern(ReadConcern.MAJORITY)
.writeConcern(WriteConcern.W1)
.build();
clientSession.startTransaction(txnOptions);

此示例展示了如何通过将 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):所有副本集成员中的大多数必须确认写入操作。

MongoDatabase database = client.getDatabase("test_database")
.withReadPreference(ReadPreference.primaryPreferred())
.withReadConcern(ReadConcern.AVAILABLE)
.withWriteConcern(WriteConcern.MAJORITY);

注意

数据库和集合是不可变的

MongoDatabaseMongoCollection 实例是不可变的。在数据库或集合上设立读取偏好(read preference)、读关注(read concern)或写关注(write concern)时,该方法会返回一个新实例,不会影响原始实例。

此示例展示了如何通过将 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):副本设立成员不需要确认写入操作。

MongoCollection<Document> collection = database.getCollection("test_collection")
.withReadPreference(ReadPreference.secondaryPreferred())
.withReadConcern(ReadConcern.AVAILABLE)
.withWriteConcern(WriteConcern.UNACKNOWLEDGED);

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

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

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

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

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

提示

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

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

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

MongoClient client = MongoClients.create(
"mongodb://<host>:<port>/?readPreference=secondary");

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

默认下, Java Reactive Streams驾驶员在选择要读取的成员时会忽略标签。要指示Java Reactive Streams驾驶员优先选择某些标签,请将标签作为列表传递给读取偏好(read preference)setter 方法。

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

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

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

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

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

List<TagSet> tagSetList = Arrays.asList(
new TagSet(new Tag("dc", "ny")),
new TagSet(new Tag("dc", "sf")),
new TagSet()
);
MongoDatabase database = client.getDatabase("test_database")
.withReadPreference(ReadPreference.secondary(tagSetList));

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

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

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

提示

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

Java Reactive Streams驾驶员使用本地阈值来计算服务器选择的延迟窗口。此值确定有资格接收读取和写入请求的服务器。

默认情况下,驱动程序仅使用 mongos 实例或副本集成员,其与最近服务器的网络探测时间在 15 毫秒以内。要在延迟较高的服务器之间分配读取,请在 MongoClientSettings 实例中设置 localThreshold 选项,或在连接 URI 中设置 localThresholdMS 选项。

注意

从单个mongos 实例选择副本集成员时, Java Reactive Streams驾驶员会忽略localThresholdMS 选项。在这种情况下,请使用mongos --localThreshold 命令行选项。

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

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("<your connection string>"))
.applyToClusterSettings(builder ->
builder.localThreshold(35, TimeUnit.MILLISECONDS))
.build();
MongoClient client = MongoClients.create(settings);
MongoClient client = MongoClients.create(
"mongodb://<host>:<port>/?localThresholdMS=35");

在前面的示例中, Java Reactive Streams驾驶员在最近节点的网络探测(ping)时间差的 35 毫秒内在匹配节点之间分配读取。

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

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

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

MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString("<your connection string>"))
.retryReads(false)
.retryWrites(false)
.build();
MongoClient client = MongoClients.create(settings);
MongoClient client = MongoClients.create(
"mongodb://<host>:<port>/?retryReads=false&retryWrites=false");

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

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