诊断多区域环境中 Azure Cosmos DB SDK 的可用性并对其进行故障排除
适用于: NoSQL
本文介绍特定区域出现连接性问题或发生区域故障转移时,最新版本的 Azure Cosmos DB SDK 的行为。
所有 Azure Cosmos DB SDK 都提供了用于自定义区域首选项的选项。 在不同的 SDK 中使用以下属性:
- .NET V2 SDK 中的 ConnectionPolicy.PreferredLocations 属性。
- .NET V3 SDK 中的 CosmosClientOptions.ApplicationRegion 或 CosmosClientOptions.ApplicationPreferredRegions 属性。
- Java V4 SDK 中的 CosmosClientBuilder.preferredRegions 方法。
- Python SDK 中的 CosmosClient.preferred_locations 参数。
- JS SDK 中的 CosmosClientOptions.ConnectionPolicy.preferredLocations 参数。
当 SDK 使用指定区域首选项的配置进行初始化时,首先将从多区域终结点获取帐户信息,包括可用区域。 然后将应用已配置的区域首选项和帐户的可用区域的交集,并使用区域首选项中的顺序确定结果的优先级。
如果区域首选项配置包含不属于帐户可用区域的区域,这些值将被忽略。 若在之后将这些无效区域添加到帐户,则 SDK 会使用这些区域(若它们在首选项配置中的优先级较高)。
帐户类型 | 读取 | 写入 |
---|---|---|
单个写入区域 | 优先级最高的首选区域 | 主要区域 |
多个写入区域 | 优先级最高的首选区域 | 优先级最高的首选区域 |
如果不设置首选区域,则 SDK 客户端将默认为主要区域:
帐户类型 | 读取 | 写入 |
---|---|---|
单个写入区域 | 主要区域 | 主要区域 |
多个写入区域 | 主要区域 | 主要区域 |
注意
主要区域是指 Azure Cosmos DB 帐户区域列表中的第一个区域。 如果指定为区域首选项的值与任何现有 Azure 区域都不匹配,则将忽略这些值。 如果这些值与某个现有区域匹配,但未将帐户复制到该区域,则客户端将会连接到下一个匹配的首选区域或者将会连接到主区域。
警告
本文档中描述的故障转移和可用性逻辑可以在客户端配置上禁用,但不建议这样做,除非用户应用程序要自己处理可用性错误。 可以通过以下方式来实现此目的:
- 将 .NET V2 SDK 中的 ConnectionPolicy.EnableEndpointDiscovery 属性设置为 false。
- 将 .NET V3 SDK 中的 CosmosClientOptions.LimitToEndpoint 属性设置为 true。
- 将 Java V4 SDK 中的 CosmosClientBuilder.endpointDiscoveryEnabled 方法设置为 false。
- 将 Python SDK 中的 CosmosClient.enable_endpoint_discovery 参数设置为 false。
- 将 JS SDK 中的 CosmosClientOptions.ConnectionPolicy.enableEndpointDiscovery 参数设置为 false。
通常情况下,SDK 客户端将连接到首选区域(如果设置了区域首选项)或主要区域(如果未设置首选项),并且操作将限于该区域,除非出现以下任何情况。
在这些情况下,使用 Azure Cosmos DB SDK 的客户端都会公开日志,并会将重试信息作为操作诊断信息的一部分包括在内:
- .NET V2 SDK 中有关响应的 RequestDiagnosticsString 属性。
- .NET V3 SDK 中有关响应和异常的 Diagnostics 属性。
- Java V4 SDK 中有关响应和异常的 getDiagnostics() 方法。
按优先级顺序确定下一个区域时,SDK 客户端将使用帐户区域列表,对首选区域(如果有)进行优先级排序。
有关这些事件中的 SLA 保证的详细信息,请参阅可用性 SLA。
从帐户中删除区域
从 Azure Cosmos DB 帐户删除区域时,任何主动使用该帐户的 SDK 客户端都将通过后端响应代码检测到区域删除。 然后,客户端将区域终结点标记为不可用。 客户端会重试当前操作,所有将来的操作将按照优先顺序永久路由到下一个区域。 如果首选项列表仅有一个条目(或为空),但该帐户还有其他可用区域,则该帐户将会路由到帐户列表中的下一个区域。
将区域添加到帐户
Azure Cosmos DB SDK 客户端每隔 5 分钟读取一次帐户配置,并刷新其识别的区域。
如果删除某个区域,然后再将其重新添加到帐户中,并且在 SDK 配置中,添加的区域的区域首选项顺序高于当前连接的区域,则 SDK 将切换回永久使用该区域。 检测到添加的区域后,所有将来的请求都将定向到该区域。
如果将客户端配置为最好连接到 Azure Cosmos DB 帐户所没有的区域,则将忽略首选区域。 如果以后添加该区域,则客户端会检测到该区域,并永久切换到该区域。
对单写入区域帐户中的写入区域进行故障转移
如果启动当前写入区域的故障转移,则下一个写入请求将失败,并返回一个已知的后端响应。 检测到此响应时,客户端将查询帐户以了解新的写入区域,然后继续重试当前操作,并将所有未来的写入操作永久路由到新区域。
区域中断
如果帐户是单个写入区域,并且在写入操作期间发生区域中断,则此行为类似于手动故障转移。 对于读取请求或多个写入区域帐户,其行为类似于删除区域。
会话一致性保证
使用会话一致性时,客户端需要保证其自身可以读取自己的写入内容。 在读取区域首选项与写入区域不同的单个写入区域帐户中,可能会出现以下情况:用户发出写入操作,当从本地区域进行读取时,本地区域尚未收到数据复制(光速约束)。 在此列情况下,SDK 会收到读取操作的服务故障,并在主要区域重试读取操作,以确保会话一致性。
TCP 协议上的暂时性连接问题
在 Azure Cosmos DB SDK 客户端配置为使用 TCP 协议的情况下,对于给定的请求,可能会出现网络状况暂时影响与特定终结点之间的通信的情况。 这些临时网络条件可能会表现为 TCP 超时和服务不可用 (HTTP 503) 错误。 如果可能,客户端将在同一终结点上本地重试请求几秒钟。
如果用户已配置了一个包含多个区域的首选区域列表,并且客户端用尽了所有本地重试,它可以尝试从首选列表中的下一个区域重试该单个操作。 仅当在 Azure Cosmos DB 帐户启用了多个写入区域时,才能在其他区域重试写入操作,但可以在任何可用区域重试读取操作。
后续步骤
- 查看可用性 SLA。
- 使用最新的 .NET SDK
- 使用最新的 Java SDK
- 使用最新的 Python SDK
- 使用最新的 Node SDK