Перенос несекционированных контейнеров в секционированные контейнеры
ОБЛАСТЬ ПРИМЕНЕНИЯ: NoSQL
Azure Cosmos DB поддерживает возможность создания контейнеров без ключа секции. В настоящее время можно создавать несекционированные контейнеры с помощью Azure CLI и пакетов SDK для Azure Cosmos DB (.NET, Java, NodeJs), версия которых меньше или равна 2.x. Вы не можете создавать несекционированные контейнеры с помощью портал Azure. Однако такие несекционированные контейнеры не являются эластичными и имеют фиксированную емкость хранилища 20 ГБ и ограничение пропускной способности в 10 000 единиц запросов в секунду.
Несекционированные контейнеры являются устаревшими, поэтому необходимо перенести существующие несекционированные контейнеры в секционированные контейнеры для масштабирования хранилища и пропускной способности. Azure Cosmos DB предоставляет системный механизм для переноса несекционированных контейнеров в секционированные контейнеры. В этом документе объясняется, как все существующие несекционированные контейнеры автоматически переносятся в секционированные контейнеры. Вы можете воспользоваться функцией автоматического переноса, только если вы используете версию sdk версии 3 на всех языках.
Примечание
В настоящее время вы не можете перенести MongoDB и API Azure Cosmos DB для учетных записей Gremlin, выполнив действия, описанные в этом документе.
Перенос контейнера с помощью системного ключа секции
В целях миграции Azure Cosmos DB предоставляет системный ключ секции /_partitionkey
для всех контейнеров, у которых нет ключа секции. Вы не можете изменить определение ключа секции после переноса контейнеров. Например, определение контейнера, перенесенного в секционированный контейнер, будет выглядеть следующим образом:
{
"Id": "CollId"
"partitionKey": {
"paths": [
"/_partitionKey"
],
"kind": "Hash"
},
}
После переноса контейнера можно создавать документы, заполняя свойство _partitionKey
вместе с другими свойствами документа. Свойство _partitionKey
представляет ключ секции документов.
Выбор правильного ключа секции важен для оптимального использования подготовленной пропускной способности. Дополнительные сведения см. в статье о выборе ключа секции.
Примечание
Функция системного ключа секции доступна, только если используются пакеты SDK последней версии или версии 3 на всех языках.
Ниже показан пример кода для создания документа с системным ключом секции и для его чтения:
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
Более старые версии SDK для Azure Cosmos DB, такие как 2.x.x и 1.x.x, не поддерживают свойство системного ключа секции. Таким образом, при чтении определения контейнера из старого пакета SDK оно не содержит определения ключа секции, и такие контейнеры работают точно так же, как и раньше. Приложения, созданные с помощью более старой версии пакетов SDK, продолжают работать с несекционированных без изменений.
Если перенесенный контейнер используется в последней версии пакета SDK или версии 3 и вы начинаете заполнять ключ секции, определенный системой, в новых документах, вы больше не сможете получить доступ к таким документам (чтение, обновление, удаление, запрос) из старых пакетов SDK.
Известные проблемы
Запрос количества элементов, которые были вставлены без ключа секции с помощью пакета SDK версии 3, может привести к повышению потребляемой пропускной способности.
При запросе из пакета SDK версии 3 элементов, вставленных с помощью пакета SDK версии 2, или элементов, вставленных с помощью пакета SDK версии 3 с параметром PartitionKey.None
, запрос количества может потреблять больше ЕЗ/с, если в FeedOptions указан параметр PartitionKey.None
. Рекомендуем не указывать параметр PartitionKey.None
, если с ключом секции не вставляются больше никакие другие элементы.
Если новые элементы вставляются с разными значениями для ключа секции, запросы к таким счетчикам элементов путем передачи соответствующего ключа в FeedOptions
не будут иметь никаких проблем. Если после вставки новых документов с ключом секции потребуется запросить только количество документов без значения ключа секции, этот запрос также может потребить больше ЕЗ/с (так же, как в обычных коллекциях с секционированием).
Дальнейшие действия
- Partitioning in Azure Cosmos DB (Секционирование в Azure Cosmos DB)
- Единицы запросов в Azure Cosmos DB
- Обеспечение необходимой пропускной способности для контейнеров и баз данных
- Работа с учетной записью Azure Cosmos DB
- Пытаетесь выполнить планирование ресурсов для миграции в Azure Cosmos DB?
- Если вам известно только количество виртуальных ядер и серверов в существующем кластере баз данных, прочитайте об оценке единиц запроса на основе этих данных.
- Если вам известна стандартная частота запросов для текущей рабочей нагрузки базы данных, ознакомьтесь со статьей о расчете единиц запросов с помощью планировщика ресурсов Azure Cosmos DB