Compartir a través de

将非分区容器迁移到分区容器

Azure Cosmos DB 支持在没有分区键的情况下创建容器。 目前,可以使用低于或等于 2.x 的版本的 Azure CLI 和 Azure Cosmos DB SDK(.NET、Java、NodeJs)创建非分区容器。 无法使用 Azure 门户创建非分区容器。 但是,此类非分区容器不是弹性的,并且固定存储容量为 20 GB,吞吐量限制为 10K RU/秒。

非分区容器是旧容器,应将现有非分区容器迁移到分区容器,以缩放存储和吞吐量。 Azure Cosmos DB 提供了一种系统定义的机制,用于将非分区容器迁移到分区容器。 本文档介绍如何将所有现有非分区容器自动迁移到分区容器。 仅当在所有语言中使用 V3 版本的 SDK 时,才能利用自动迁移功能。

注释

目前,无法使用本文档中所述的步骤迁移 Gremlin 帐户的 Azure Cosmos DB MongoDB 和 API。

使用系统定义的分区键迁移容器

为了支持迁移,Azure Cosmos DB 提供了一个系统定义的分区键,该分区键在没有分区键的所有容器上命名 /_partitionkey 。 迁移容器后,无法更改分区键定义。 例如,迁移到分区容器的容器的定义如下所示:

{
    "Id": "CollId"
  "partitionKey": {
    "paths": [
      "/_partitionKey"
    ],
    "kind": "Hash"
  },
}

迁移容器后,可以通过填充 _partitionKey 属性以及文档的其他属性来创建文档。 该 _partitionKey 属性表示文档的分区键。

选择正确的分区键对于以最佳方式利用预配的吞吐量非常重要。 有关详细信息,请参阅 如何选择分区键 文章。

注释

仅当在所有语言中使用最新的 V3 版本 SDK 时,才能利用系统定义的分区键。

以下示例演示了使用系统定义的分区键创建文档并读取该文档的示例代码:

文档的 JSON 表示形式

DeviceInformationItem = new DeviceInformationItem
{
   "id": "elevator/PugetSound/Building44/Floor1/1",
   "deviceId": "3cf4c52d-cc67-4bb8-b02f-f6185007a808",
   "_partitionKey": "3cf4c52d-cc67-4bb8-b02f-f6185007a808"
}

public class DeviceInformationItem
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }

    [JsonProperty(PropertyName = "deviceId")]
    public string DeviceId { get; set; }

    [JsonProperty(PropertyName = "_partitionKey", NullValueHandling = NullValueHandling.Ignore)]
    public string PartitionKey { get {return this.DeviceId; set; }
}

CosmosContainer migratedContainer = database.Containers["testContainer"];

DeviceInformationItem deviceItem = new DeviceInformationItem() {
  Id = "1234",
  DeviceId = "3cf4c52d-cc67-4bb8-b02f-f6185007a808"
}

ItemResponse<DeviceInformationItem > response =
  await migratedContainer.CreateItemAsync<DeviceInformationItem>(
    deviceItem.PartitionKey,
    deviceItem
  );

// Read back the document providing the same partition key
ItemResponse<DeviceInformationItem> readResponse =
  await migratedContainer.ReadItemAsync<DeviceInformationItem>(
    partitionKey: deviceItem.PartitionKey,
    id: device.Id
  );

有关完整示例,请参阅 .NET 示例 GitHub 存储库。

迁移文档

虽然容器定义使用分区键属性进行了增强,但不会自动迁移容器中的文档。 这意味着系统分区键属性 /_partitionKey 路径不会自动添加到现有文档。 需要通过读取没有分区键创建的文档,对现有文档进行重新分区,并在重新编写时把 _partitionKey 属性写入到文档中。

访问没有分区键的文档

应用程序可以使用名为“PartitionKey.None”的特殊系统属性访问没有分区键的现有文档,这是非迁移文档的值。 可以在所有 CRUD 和查询作中使用此属性。 以下示例演示了从 NonePartitionKey 读取单个文档的示例。

CosmosItemResponse<DeviceInformationItem> readResponse =
await migratedContainer.Items.ReadItemAsync<DeviceInformationItem>(
  partitionKey: PartitionKey.None,
  id: device.Id
);

与 SDK 的兼容性

旧版 Azure Cosmos DB SDK(如 V2.x.x 和 V1.x.x)不支持系统定义的分区键属性。 因此,从较旧的 SDK 读取容器定义时,它不包含任何分区键定义,并且这些容器的行为与以前完全相同。 使用旧版 SDK 构建的应用程序将继续按原样使用非分区,无需进行任何更改。

如果已迁移的容器由最新/V3 版本的 SDK 使用,并且开始在新文档中填充系统定义的分区键,则无法再从旧版 SDK 访问此类文档(读取、更新、删除、查询)。

已知问题

使用 V3 SDK 查询未使用分区键插入的项的数量可能会导致较高的吞吐量消耗。

如果您从 V3 SDK 查询由 V2 SDK 插入的项,或者查询使用 V3 SDK 和 PartitionKey.None 参数插入的项,那么当在 FeedOptions 中提供 PartitionKey.None 参数时,计数查询可能会消耗更多的 RU/秒。 建议在没有使用分区键插入其他项时,不要提供 PartitionKey.None 参数。

如果使用分区键的不同值插入新项,则通过传入相应的键 FeedOptions 来查询此类项计数没有任何问题。 使用分区键插入新文档后,如果需要仅查询文档计数且不使用分区键值,该查询可能会再次产生与常规分区集合类似的资源消耗水平(RU/s)。

后续步骤