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 平台上受支持。

Azure Cosmos DB 连接模式的关系图。

这些连接模式实质上是数据平面请求(文档读取和写入)从客户端计算机到 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), 图形 (443)
直接 (通过 TLS 加密的) TCP .NET SDK Java SDK 使用公共/服务终结点时:端口介于 10000 到 20000 之间

使用专用终结点时:端口介于 0 到 65535 之间

直接模式连接体系结构

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

路由

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

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

此图显示了 SDK 在直接模式下如何从网关提取容器和路由信息,然后再打开与后端节点的 TCP 连接。

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

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

连接量

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

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

  • 物理分区数

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

  • 并发请求数

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

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

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

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

后续步骤

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

尝试为迁移到 Azure Cosmos DB 进行容量计划? 可以使用有关现有数据库群集的信息进行容量规划。