教程:使用 API for NoSQL 设置 Azure Cosmos DB 多区域分布

适用于: NoSQL

本文介绍如何使用 Azure 门户设置 Azure Cosmos DB 多区域分布,然后使用 API for NoSQL 进行连接。

本文涵盖以下任务:

  • 使用 Azure 门户配置多区域分布
  • 使用 API for NoSQL 配置多区域分布

使用 Azure 门户添加多区域数据库区域

Azure Cosmos DB 面向中国的所有 Azure 区域提供。 为数据库帐户选择默认的一致性级别后,可以关联一个或多个区域(具体取决于所选的默认一致性级别和多区域分布需求)。

  1. Azure 门户的左侧栏中,单击“Azure Cosmos DB”

  2. 在“Azure Cosmos DB”页中,选择要修改的数据库帐户。

  3. 在“帐户”页上的菜单中单击“全局复制数据”。

  4. 在“全局复制数据”页中,通过单击地图中的区域选择要添加或删除的区域,并单击“保存”。 添加区域会产生费用,有关详细信息,请参阅定价页使用 Azure Cosmos DB 多区域分布数据一文。

    单击图中的区域可以添加或删除区域

添加第二个区域后,门户中的“全局复制数据”页上会启用“手动故障转移”选项。 可以使用此选项测试故障转移过程或更改主写入区域。 添加第三个区域后,会在同一页上启用“故障转移优先级”选项,以便更改读取的故障转移顺序。

选择多区域数据库区域

配置两个或更多区域有两个常见方案:

  1. 向最终用户提供对数据的低延迟访问,而无论用户位于中国的何位置
  2. 添加区域复原以实现业务连续性和灾难恢复 (BCDR)

若要向最终用户提供低延迟,建议在与应用程序用户所在位置对应的区域中同时部署应用程序和 Azure Cosmos DB。

若要实现 BCDR,建议按照Azure 中的跨区域复制:业务连续性和灾难恢复一文中所述,根据区域对添加区域。

使用 API for NoSQL 连接到首选区域

为了利用多区域分发,客户端应用程序可以指定要用于执行文档操作的区域优先顺序列表。 SQL SDK 会根据 Azure Cosmos DB 帐户配置、当前区域可用性和指定的优先顺序列表,选择最佳的终结点来执行写入和读取操作。

此优先顺序列表是在使用 SQL SDK 初始化连接时指定的。 SDK 接受可选参数 PreferredLocations,这是 Azure 区域的顺序列表。

SDK 会自动将所有写入请求发送到当前写入区域。 所有读取请求将发送到首选位置列表中的第一个可用区域。 如果请求失败,客户端会将请求转发到列表中的下一个区域。

SDK 只会尝试读取首选位置中指定的区域。 因此,例如,如果 Azure Cosmos DB 帐户在四个区域中可用,但客户端只在 PreferredLocations 内指定了两个读取(非写入)区域,那么将不会从 PreferredLocations 中未指定的读取区域为读取提供服务。 如果 PreferredLocations 列表中指定的读取区域不可用,将从写入区域为读取提供服务。

应用程序可以通过检查 SDK 1.8 和更高版本中提供的两个属性(WriteEndpointReadEndpoint)来验证 SDK 选择的当前写入终结点和读取终结点。 如果未设置 PreferredLocations 属性,则会从当前写入区域为所有请求提供服务。

如果未指定首选位置但使用了 setCurrentLocation 方法,则 SDK 会根据客户端运行的当前区域自动填充首选位置。 SDK 会根据一个区域与当前区域的邻近程度对区域进行排序。

.NET SDK

无需进行任何代码更改即可使用该 SDK。 在此情况下,SDK 会自动将读取和写入请求定向到当前写入区域。

在 .NET SDK 1.8 和更高版本中,DocumentClient 构造函数的 ConnectionPolicy 参数有一个名为 Microsoft.Azure.Documents.ConnectionPolicy.PreferredLocations 的属性。 此属性的类型为 Collection <string>,应包含区域名称的列表。 字符串值已根据 Azure 区域页上的“区域名称”列设置格式,其第一个字符的前面和最后一个字符的后面均没有空格。

当前写入终结点和读取终结点分别在 DocumentClient.WriteEndpoint 和 DocumentClient.ReadEndpoint 中提供。

注意

不应将终结点 URL 视为长期不变的常量。 服务随时会更新这些 URL。 SDK 会自动处理这种更改。

如果使用的是 .NET V2 SDK,请使用 PreferredLocations 属性设置首选区域。

// Getting endpoints from application settings or other configuration location
Uri accountEndPoint = new Uri(Properties.Settings.Default.GlobalDatabaseUri);
string accountKey = Properties.Settings.Default.GlobalDatabaseKey;
  
ConnectionPolicy connectionPolicy = new ConnectionPolicy();

//Setting read region selection preference
connectionPolicy.PreferredLocations.Add(LocationNames.ChinaNorth); // first preference
connectionPolicy.PreferredLocations.Add(LocationNames.ChinaNorth); // second preference
connectionPolicy.PreferredLocations.Add(LocationNames.NorthEurope); // third preference

// initialize connection
DocumentClient docClient = new DocumentClient(
    accountEndPoint,
    accountKey,
    connectionPolicy);

// connect to DocDB
await docClient.OpenAsync().ConfigureAwait(false);

或者可使用 SetCurrentLocation 属性,让 SDK 根据邻近程度选择首选位置。

// Getting endpoints from application settings or other configuration location
Uri accountEndPoint = new Uri(Properties.Settings.Default.GlobalDatabaseUri);
string accountKey = Properties.Settings.Default.GlobalDatabaseKey;
  
ConnectionPolicy connectionPolicy = new ConnectionPolicy();

connectionPolicy.SetCurrentLocation("China North 2"); /

// initialize connection
DocumentClient docClient = new DocumentClient(
    accountEndPoint,
    accountKey,
    connectionPolicy);

// connect to DocDB
await docClient.OpenAsync().ConfigureAwait(false);

Node.js/JavaScript

注意

不应将终结点 URL 视为长期不变的常量。 服务随时会更新这些 URL。 SDK 会自动处理这种更改。

下面是 Node.js/JavaScript 的代码示例。

// Setting read region selection preference, in the following order -
// 1 - China North2
// 2 - China North3
// 3 - China East2
const preferredLocations = ['China North2', 'China North3', 'China East2'];

// initialize the connection
const client = new CosmosClient{ endpoint, key, connectionPolicy: { preferredLocations } });

Python SDK

以下代码演示如何使用 Python SDK 设置首选位置:

connectionPolicy = documents.ConnectionPolicy()
connectionPolicy.PreferredLocations = ['China North', 'China North', 'China North']
client = cosmos_client.CosmosClient(ENDPOINT, {'masterKey': MASTER_KEY}, connectionPolicy)

Java V4 SDK

以下代码演示如何使用 Java SDK 设置首选位置:

Java SDK V4 (Maven com.azure::azure-cosmos) 异步 API

// Getting endpoints from application settings or other configuration location
Uri accountEndPoint = new Uri(Properties.Settings.Default.GlobalDatabaseUri);
string accountKey = Properties.Settings.Default.GlobalDatabaseKey;
  
ConnectionPolicy connectionPolicy = new ConnectionPolicy();

//Setting read region selection preference
connectionPolicy.PreferredLocations.Add(LocationNames.ChinaEast2); // first preference
connectionPolicy.PreferredLocations.Add(LocationNames.China Nroth2); // second preference
connectionPolicy.PreferredLocations.Add(LocationNames.ChinaNorth3); // third preference

// initialize connection
DocumentClient docClient = new DocumentClient(
    accountEndPoint,
    accountKey,
    connectionPolicy);

// connect to DocDB
await docClient.OpenAsync().ConfigureAwait(false);

Spark 3 连接器

可以使用 spark.cosmos.preferredRegionsList 配置定义首选区域列表,例如:

val sparkConnectorConfig = Map(
  "spark.cosmos.accountEndpoint" -> cosmosEndpoint,
  "spark.cosmos.accountKey" -> cosmosMasterKey,
  "spark.cosmos.preferredRegionsList" -> "[China North2, China North3, China East2]"
  // other settings
)

REST

数据库帐户在多个区域中可用后,客户端可以通过对此 URI https://{databaseaccount}.documents.azure.cn/ 执行 GET 请求来查询该帐户的可用性

服务将返回副本的区域及其对应 Azure Cosmos DB 终结点 URI 的列表。 当前写入区域会在响应中指示。 然后,客户端可为所有其他 REST API 请求选择适当的终结点,如下所示。

示例响应

{
    "_dbs": "//dbs/",
    "media": "//media/",
    "writableLocations": [
        {
            "Name": "China North2",
            "DatabaseAccountEndpoint": "https://globaldbexample-chinanorth.documents.azure.cn:443/"
        }
    ],
    "readableLocations": [
        {
            "Name": "China North3",
            "DatabaseAccountEndpoint": "https://globaldbexample-chinanorth.documents.azure.cn:443/"
        }
    ],
    "MaxMediaStorageUsageInMB": 2048,
    "MediaStorageUsageInMB": 0,
    "ConsistencyPolicy": {
        "defaultConsistencyLevel": "Session",
        "maxStalenessPrefix": 100,
        "maxIntervalInSeconds": 5
    },
    "addresses": "//addresses/",
    "id": "globaldbexample",
    "_rid": "globaldbexample.documents.azure.cn",
    "_self": "",
    "_ts": 0,
    "_etag": null
}
  • 所有 PUT、POST 和 DELETE 请求必须转到指示的写入 URI
  • 所有 GET 和其他只读请求(例如查询)可以转到客户端选择的任何终结点

向只读区域发出的写入请求会失败并出现 HTTP 错误代码 403(“禁止”)。

如果在客户端初始发现阶段过后写入区域发生更改,则向先前写入区域进行的后续写入会失败并出现 HTTP 错误代码 403(“禁止”)。 然后,客户端应再次对区域列表执行 GET 以获取更新的写入区域。

本教程到此结束。 阅读 Azure Cosmos DB 中的一致性级别,了解如何管理多区域复制帐户的一致性。 有关 Azure Cosmos DB 中多区域数据库复制工作原理的详细信息,请参阅使用 Cosmos DB 多区域分配数据

后续步骤

在本教程中已完成以下操作:

  • 使用 Azure 门户配置多区域分发
  • 使用 API for NoSQL 配置多区域分布

现在可以继续学习下一个教程,了解如何使用 Azure Cosmos DB 本地模拟器在本地开发。

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