Azure Cosmos DB SQL SDK 连接模式

适用范围: NoSQL

客户端连接到 Azure Cosmos DB 的方式对性能有重大影响,尤其是在观察到的客户端延迟方面。 Azure Cosmos DB 提供基于 HTTPS 的简单开放式 RESTful 编程模型(称为网关模式)。 此外,它还提供了高效的 TCP 协议,该协议在其通信模型中也是 RESTful,并使用 TLS 进行初始身份验证和加密流量(称为直接模式)。

可用的连接模式

两种可用的连接模式为:

  • 网关模式

    可在任意 SDK 平台上使用网关模式。 如果应用程序在有严格防火墙限制的企业网络中运行,则网关模式是最佳选择,因为它使用标准 HTTPS 端口与单个 DNS 终结点。 但是,对于性能的影响是:每次在 Azure Cosmos DB 中读取或写入数据时,网关模式都涉及到额外的网络跃点。 在套接字连接数量有限的环境中运行应用程序时,我们也建议使用网关连接模式。

    在 Azure Functions 中使用 SDK 时,尤其是在消耗计划中使用时,请注意当前的连接限制

  • 直接模式

    直接模式支持通过 TCP 协议进行连接,使用 TLS 进行初始身份验证和加密流量,并提供更好的性能,因为网络跃点较少。 应用程序直接连接到后端副本。 直接模式目前仅在 .NET 和 Java SDK 平台上受支持。

The Azure Cosmos DB connectivity modes

这些连接模式实质上限制了数据平面请求(文档读取和写入)从客户端计算机到 Azure Cosmos DB 后端中的分区的路由方式。 直接模式是获得最佳性能的首选选项,它允许客户端直接与 Azure Cosmos DB 后端中的分区建立 TCP 连接,并且在不通过中介的情况下直接发送请求。 与之相反,在网关模式下,客户端发出的请求会路由到 Azure Cosmos DB 前端中所谓的“网关”服务器,该服务器接下来会将你的请求扇出到 Azure Cosmos DB 后端的相应分区。

服务端口范围

当你使用直接模式时,需要确保客户端可以访问 10000 到 20000 之间的端口,因为 Azure Cosmos DB 使用动态 TCP 端口。 这是对网关端口的补充。 在专用终结点上使用直接模式时,Azure Cosmos DB 可以使用从 0 到 65535 的完整 TCP 端口范围。 如果客户端上的这些端口未处于打开状态,你可能会在尝试使用 TCP 协议时收到“503 服务不可用”错误。

下表显示了可用于各种 API 的连接模式以及用于每个 API 的服务端口的摘要:

连接模式 支持的协议 支持的 SDK API/服务端口
网关 HTTPS 所有 SDK SQL (443)、MongoDB (10255)、表 (443)、Cassandra (10350)、Graph (443)
直接 (通过 TLS 加密的) TCP .NET SDK Java SDK 使用公共/服务终结点时:端口介于 10000 到 20000 之间
使用专用终结点时:端口介于 0 到 65535 之间

直接模式连接体系结构

简介中所述,直接模式客户端将通过 TCP 协议直接连接到后端节点。 每个后端节点都代表属于物理分区副本集中的一个副本。

路由

当直接模式下的 Azure Cosmos DB SDK 执行操作时,需要解析要连接到的后端副本。 第一步是了解操作应转到哪个物理分区,为此,SDK 从网关节点获取包含分区键定义的容器信息。 它还需要包含副本 TCP 地址的路由信息。 也可从网关节点获取路由信息,两者都被视为控制平面元数据。 SDK 获取路由信息后,可以继续打开与属于目标物理分区的副本的 TCP 连接并执行操作。

每个副本集都包含一个主要副本和三个次要副本。 写入操作始终路由到主副本节点,而读取操作可从主节点或辅助节点提供。

Diagram that shows how S D Ks in direct mode fetch the container and routing information from Gateway before opening the T C P connections to the backend nodes

由于容器和路由信息不会经常更改,因此会在 SDK 上本地缓存,以便后续操作可以从此信息中受益。 也可跨操作重用已经建立的 TCP 连接。 除非通过 SDK 选项另外配置,否则连接将在 SDK 实例的生存期内永久保持。

与任何分布式体系结构一样,持有副本的计算机可能会进行升级或维护。 此服务将确保副本集保持一致性,但任何副本移动都会导致现有 TCP 地址发生更改。 在此类情况下,SDK 需要刷新路由信息,并通过新的网关请求重新连接到新地址。 这些事件不应影响总体 P99 SLA。

连接量

每个物理分区都有一个包含四个副本的副本集,为了提供可能的最佳性能,SDK 最终将针对混合写入和读取操作的工作负载打开与所有副本的连接。 并发操作跨现有连接进行负载均衡,以利用每个副本提供的吞吐量。

有两个因素决定 SDK 将打开的 TCP 连接数:

  • 物理分区数

    在稳定状态下,SDK 将为每个物理分区的每个副本建立一个连接。 容器中物理分区数越大,打开的连接数就越多。 由于操作跨不同分区进行路由,因此可以根据需要建立连接。 平均连接数将是物理分区数乘以 4 所得到的结果。

  • 并发请求数

    每个已建立的连接都可提供可配置数量的并发操作。 如果并发操作量超过此阈值,则新连接将打开以提供服务,并且在物理分区中,打开的连接数可能超过稳定状态数。 对于可能在其操作量中出现峰值的工作负载,预期会出现此行为。 对于 .NET SDK,此配置由 CosmosClientOptions.MaxRequestsPerTcpConnection 设置,对于 Java SDK,可使用 DirectConnectionConfig.setMaxRequestsPerConnection 进行自定义。

默认情况下,连接将永久保持,以提高未来的操作的性能(打开连接会产生计算开销)。 在某些情况下,你可能希望关闭在一段时间内未使用的连接,因为这可能会稍微影响未来的操作。 对于 .NET SDK,此配置由 CosmosClientOptions.IdleTcpConnectionTimeout 设置,对于 Java SDK,可使用 DirectConnectionConfig.setIdleConnectionTimeout 进行自定义。 不建议将这些配置设置为低值,因为它可能会导致连接频繁关闭并影响整体性能。

特定于语言的实现详细信息

有关语言的进一步实现详细信息,请参阅:

后续步骤

对于特定 SDK 平台性能优化: