Секционирование и горизонтальное масштабирование в Azure Cosmos DB

ПРИМЕНИМО К: API SQL API Cassandra API Gremlin API таблиц API Azure Cosmos DB для MongoDB

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

Например, контейнер содержит элементы. Каждый элемент имеет уникальное значение для свойства UserID. Если в контейнере в качестве ключа секции для элементов используется свойство UserID и есть 1000 уникальных значений UserID, то для этого контейнера будет создано 1000 логических секций.

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

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

Логические секции

Логическая секция состоит из набора элементов с одинаковым ключом секции. Например, в контейнере, в котором представлены данные о продуктах питания, все элементы содержат свойство foodGroup. Это свойство foodGroup можно использовать в качестве ключа секции для контейнера. Группы элементов с определенными значениями для foodGroup, например Beef Products, Baked Products и Sausages and Luncheon Meats, формируют отдельные логические секции.

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

Количество логических секций в контейнере не ограничено. В каждой логической секции может храниться до 20 ГБ данных. Удачный выбор ключа секции подразумевает широкий диапазон возможных значений. Например, в контейнере, где все элементы содержат свойство foodGroup, размер данных в логической секции Beef Products может достигнуть 20 ГБ. Выбор ключа секции с широким диапазоном возможных значений гарантирует, что контейнер сможет масштабироваться.

Физические секции

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

На количество физических секций в контейнере влияют указанные ниже факторы.

  • Объем подготовленной пропускной способности. (Каждая отдельная физическая секция может обеспечить пропускную способность до 10 000 единиц запросов в секунду.) Ограничение в 10 000 единиц запросов в секунду для физических секций подразумевает, что для логических секций также установлено ограничение в 10 000 единиц запросов в секунду, так как каждая логическая секция сопоставлена только с одной физической секцией.

  • Общий объем хранилища данных. (Каждая отдельная физическая секция может хранить до 50 ГБ данных).

Примечание

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

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

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

Сведения о физических секциях контейнера можно просмотреть на портале Azure в колонке Метрики в разделе Хранилище.

Просмотр сведений о количестве физических секций

На приведенном выше снимке экрана качестве ключа секции для контейнера использоваться свойство /foodGroup. Каждый из трех столбцов в графе — это физическая секция. На этом изображении диапазон ключей секции совпадает с физической секцией. Выбранная физическая секция содержит 3 основные логические секции наибольшего размера: Beef Products, Vegetable and Vegetable Products и Soups, Sauces, and Gravies.

Если подготовленная пропускная способность поддерживает 18 000 единиц запросов в секунду, то каждая из трех физических секций может использовать 1/3 от общего значения. В пределах выбранной физической секции ключи логических секций Beef Products, Vegetable and Vegetable Products и Soups, Sauces, and Gravies в совокупности могут использовать 6000 единиц запросов в секунду от подготовленной пропускной способности. Подготовленная пропускная способность равномерно распределяется по физическим секциям контейнера, поэтому важно выбрать правильный ключ логической секции, который равномерно распределит потребление пропускной способности.

Управление логическими секциями

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

Azure Cosmos DB распределяет логические секции между физическими путем секционирования на основе хэша. Azure Cosmos DB хэширует значение ключа секции для элемента. Результат хэширования определяет физическую секцию. Затем Azure Cosmos DB равномерно распределяет пространство для хэшей ключей секций по физическим секциям.

Транзакции (в хранимых процедурах или триггерах) допустимы только для элементов в одной логической секции.

Наборы реплик

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

Обычно для небольших контейнеров требуется только одна физическая секция, но они будут иметь по крайней мере 4 реплики.

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

Изображение, на котором показан механизм секционирования в Azure Cosmos DB

Выбор ключа секции

Ключ секции содержит два компонента: путь и значение. Например, рассмотрим элемент { "userId" : "Andrew", "worksFor": "Microsoft" }. Если в качестве ключа секции выбрать "userId", то он будет состоять из двух указанных ниже компонентов.

  • Путь к ключу секции (например, "/userId"), который может содержать буквы, цифры и символы подчеркивания (_). Вы также можете использовать вложенные объекты также с помощью стандартной нотации пути (/).

  • Значение ключа секции (например, "Andrew"), которое может быть строкой или числовыми данными.

Дополнительные сведения об ограничениях пропускной способности, хранилища и длины ключа секции см. в статье о квотах для службы Azure Cosmos DB.

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

Для всех контейнеров ключ секции должен обладать перечисленными ниже свойствами.

  • В качестве ключа секции должно использоваться свойство со значением, которое не изменяется. Если свойство является ключом секции, его значение невозможно обносить.

  • Высокая кратность. Другими словами, свойство должно иметь широкий диапазон возможных значений.

  • Потребление единиц запроса и хранение данных должно быть равномерно распределено по всем логическим секциям. Это обеспечивает равномерное потребление единиц запроса и распределение объемов хранилища по физическим секциям.

Если вам необходимы транзакции ACID для нескольких элементов в Azure Cosmos DB, потребуется использовать хранимые процедуры или триггеры. Все хранимые процедуры и триггеры на основе JavaScript ограничены одной логической секцией.

Ключи секций для контейнеров с высокой интенсивностью чтения

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

Если большая часть рабочей нагрузки — это запросы, а в большинстве запросов применен фильтр равенства для одного и того же свойства, то выбор этого свойства в качестве ключа секции может быть хорошим решением. Например, если часто выполняется запрос c фильтрацией по UserID, то при выборе UserID в качестве ключа секции уменьшится количество запросов между секциями.

У небольших контейнеров, как правило, немного секций, и вам не нужно беспокоиться о влиянии запросов между разделами на производительность. Большинству таких контейнеров в Azure Cosmos DB требуется только одна или две физические секции.

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

  • в контейнере будет подготовлено более 30 000 единиц запросов;

  • в контейнере будет храниться более 100 ГБ данных.

Использование идентификатора элемента в качестве ключа секции

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

Системное свойство идентификатор элемента есть в каждом элементе контейнера. У вас могут быть и другие свойства, которые представляют собой логический идентификатор элемента. Во многих случаях они также будут отличными ключами секции по тем же причинам, что и идентификатор элемента.

Использование идентификатор элемента в качестве ключа секции — это удачный выбор по нескольким причинам, перечисленным ниже.

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

При выборе идентификатора элемента в качестве ключа секции учитывайте перечисленные ниже моменты.

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

Дальнейшие действия