Разбивайте коллекции с помощью драйвера C # MongoDB с Azure Cosmos DB.

Azure Cosmos DB - это полностью управляемая база данных NoSQL. Я много писал об этом в этом блоге. Продвинутая и мощная функция - это возможность разбивать данные на разделы. Обычно это называется сегментированием. Azure Cosmos DB справится с этим за вас, если вы выполните эти предварительные требования для разделения.

Я не буду вдаваться в подробности о разбиении, потому что это хорошо объяснено в документации. Вкратце, логический раздел - это набор сгруппированных вместе элементов. Это определяется свойством документов, которое может быть либо хешировано, либо указано как диапазон. Логично, что элементы с одним и тем же ключом раздела хранятся вместе. Физически узел может хранить от одного до нескольких разделов или шардов. Azure Cosmos DB прозрачно выполняет это для вас по запросу.

Прочтите все, что нужно знать о секционировании, здесь: Секционирование и масштабирование в Azure Cosmos DB

Ключи секционирования помогают с масштабированием, особенно когда ваша база данных географически распределена. Это связано с тем, что при вставке или обновлении элементов репликация может сосредоточиться на этом конкретном разделе, а не на всей базе данных. Чтения также можно оптимизировать, разместив разделы для этих чтений. Поведение репликации оптимизируется путем установки определенного уровня согласованности.

Хотя в документации обсуждается, как секционирование работает в различных API-интерфейсах (для обзора различных API-интерфейсов и доступных разновидностей баз данных, прочтите Обзор API-интерфейсов Azure Cosmos DB), не было явного примера того, как установить ключ раздела через код.

Я начал с моего существующего примера базы данных USDA. Он содержит почти 9000 продуктов, отнесенных к определенной пищевой группе. Есть много лучших практик по выбору ключа раздела. Чтобы упростить этот пример, я решил разделить FoodGroupId property.

Код для создания коллекции в MongoDB выглядит так:

Чтобы указать ключ раздела, мы должны создать сегментированную коллекцию. Это делается путем передачи команды в базу данных. Команды и запросы MongoDB - это все документы JSON, поэтому мы можем использовать BsonDocument class драйвера для создания команды. Это команда для создания сегментированной коллекции:

Имя коллекции передается как полностью определенная база данных и имя коллекции, за которыми следует ключ для сегмента, указывающий на хэш FoodGroupId. Документ используется для создания команды и затем передается в базу данных.

После вставки данных вы можете просмотреть распределение хранилища по ключам разделов на портале.

Вы можете видеть, что есть несколько выбросов с большим объемом хранилища, но в целом хранилище распределено равномерно. Вы указываете ключ раздела, чтобы создать логический раздел, который гарантирует, что элементы с одним и тем же хешем ключа будут вместе. Cosmos DB управляет физическими разделами в зависимости от потребностей. На портале вы можете видеть, что, хотя у нас есть несколько десятков ключей разделов, существует только несколько разделов.

Разделы упорядочены. Я выделил «раздел 3», содержащий 40 мегабайт данных. При нажатии на раздел отображаются содержащиеся в нем логические ключи.

Каждый документ в коллекции должен иметь ключ раздела, в противном случае выдается ошибка при попытке вставить или обновить его. Чтобы увидеть, как работает разделение с точки зрения производительности и стоимости, я сначала выполнил поиск текста, «зашифрованного» по всей базе данных (несколько физических и логических разделов).

Если вас смущает синтаксис JSON, который я использую для запросов MongoDB, вы можете узнать больше о нем и о том, как он соотносится с синтаксисом SQL, здесь: Документы запросов MongoDB.

Единица запроса представляет собой фиксированный объем памяти, хранилища и ЦП, необходимый для выполнения операции. Здесь у нас почти 4000 RU для выполнения запроса. Запрос должен был сканировать каждый элемент и применять регулярное выражение. Давайте сузим его до двух уникальных групп продуктов, которые были возвращены. Этот запрос будет охватывать два логических раздела и просто два физических раздела (0100 находится в другом разделе, чем 2100).

Фильтр значительно сократил количество RU, но это в основном связано с тем, что механизм запросов использует встроенные индексы для сужения подмножества элементов для сканирования. Если мы ограничим запрос одним разделом (как логическим, так и физическим), производительность снова резко улучшится:

Преимущество в производительности связано не только с ограниченным количеством проверяемых записей. Мы можем ограничить записи одним и тем же подмножеством, используя другой столбец, который не является ключом раздела (описание группы, а не его уникальный идентификатор), и количество единиц RU увеличится, поскольку оно не ограничено один раздел:

Увеличение не столь значимо для мегабайт данных, но будет более очевидным при работе с терабайтами и петабайтами данных.

Если вы переходите на Azure Cosmos DB из MongoDB или просто заинтересованы в использовании API MongoDB, теперь вы знаете, как воспользоваться преимуществами ключей секций для масштабной репликации с помощью Azure Cosmos DB. Концепция аналогична другим API, но реализации различаются.

Готовы начать работу с MongoDB API? Прочтите Введение в Azure Cosmos DB с API MongoDB.

С уважением,