Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Azure Cosmos DB использует секционирование для масштабирования контейнеров в базе данных в соответствии с потребностями в производительности приложения. Элементы в контейнере делятся на отдельные подмножества, называемые логическими секциями. Логические разделы формируются на основе значения ключа раздела, связанного с каждым элементом в контейнере. Все элементы в логической секции имеют одинаковое значение ключа секции.
Например, контейнер содержит элементы. Каждый элемент имеет уникальное значение для свойства UserID. Если в контейнере в качестве ключа секции для элементов используется свойство UserID и есть 1000 уникальных значений UserID, то для этого контейнера будет создано 1000 логических секций.
Каждый элемент в контейнере имеет ключ секции , который определяет свою логическую секцию и идентификатор элемента , уникальный внутри этой секции. Сочетание ключа секции и идентификатора элемента создает индекс, который однозначно определяет элемент. Выбор ключа партиции — это важное решение, которое влияет на производительность вашего приложения.
Замечание
В некоторых распределенных системах баз данных и материалах обучения ключ сегментов используется для описания свойства, определяющего распределение данных между сегментами. В Azure Cosmos DB эта же концепция называется ключом секции.
Оба термина ссылаются на значение, используемое для распределения и поиска данных, но ключ раздела является официальным и правильным термином, используемым в документации и API Azure Cosmos DB.
В этой статье описывается связь между логическими и физическими секциями, рассматриваются рекомендации по секционированию и предоставляется подробное представление о том, как работает горизонтальное масштабирование в Azure Cosmos DB. Вам не нужно понимать эти внутренние сведения, чтобы выбрать ключ секции, но в этой статье описано, как работает Azure Cosmos DB.
Логические разделы
Логическая секция — это набор элементов, которые используют один и тот же ключ секции. Например, в контейнере, в котором представлены данные о продуктах питания, все элементы содержат свойство foodGroup. Используйте foodGroup в качестве ключа раздела для контейнера. Группы элементов с определенными значениями для foodGroup, например Beef Products, Baked Products и Sausages and Luncheon Meats, формируют отдельные логические секции.
Логическая секция также определяет область транзакций базы данных. Элементы в логическом разделе можно обновить, используя транзакцию с изоляцией моментального снимка. При добавлении новых элементов в контейнер система прозрачно создает новые логические секции. Вы можете не беспокоиться об удалении логической секции при удалении базовых данных.
Количество логических секций в контейнере не ограничено. Каждая логическая секция может хранить до 20 ГБ данных. Рациональные ключи партиций имеют широкий диапазон возможных значений. Например, в контейнере, где все элементы содержат свойство foodGroup, размер данных в логической секции Beef Products может достигнуть 20 ГБ.
Выбор ключа секции с широким диапазоном возможных значений гарантирует, что контейнер сможет масштабироваться.
Если у вас есть сценарии, в которых ключи секций могут превышать 20 ГБ данных, использование иерархических ключей секций может помочь. Если вы используете эту функцию, можно настроить до трехуровневой иерархии для ключей секций для дальнейшего оптимизации распределения данных и повышения уровня масштабирования. См. обзор иерархических ключей секций.
Используйте оповещения Azure Monitor, чтобы отслеживать, приближается ли размер логического раздела к 20 ГБ.
Физические разделы
Контейнер масштабируется путем распределения данных и пропускной способности между физическими секциями. Внутри одна или несколько логических разделов сопоставляются с одним физическим разделом. Как правило, небольшие контейнеры имеют множество логических секций, но требуют только одной физической секции. В отличие от логических секций, физические секции являются внутренней реализацией системы, и Azure Cosmos DB полностью управляет ими.
Количество физических секций в контейнере зависит от следующих характеристик:
Подготовленная пропускная способность. (Каждая отдельная физическая секция может обеспечить пропускную способность до 10 000 единиц запросов в секунду.) Ограничение в 10 000 единиц запросов в секунду для физических секций подразумевает, что для логических секций также установлено ограничение в 10 000 единиц запросов в секунду, так как каждая логическая секция сопоставлена только с одной физической секцией.
Общее хранилище данных (каждая отдельная физическая секция может хранить до 50 гигабайт данных).
Замечание
Физические секции — это внутренняя реализация системы, полностью управляемая Azure Cosmos DB. При разработке решений не сосредотачивайтесь на физических секциях, так как вы не можете ими управлять. Вместо этого сосредоточьтесь на ключах секций. Выбор ключа секции, равномерно распределяющего потребление пропускной способности между логическими секциями, обеспечивает сбалансированное потребление пропускной способности между физическими секциями.
Общее количество физических секций в контейнере не ограничено. По мере увеличения подготовленной пропускной способности или размера данных Azure Cosmos DB автоматически создает новые физические секции, разделяя существующие. Разделения физических разделов не влияют на доступность вашего приложения. После разделения физической секции все данные из одной логической секции будут по-прежнему храниться в той же физической секции. При разделении физической секции просто создается новое сопоставление логических секций с физическими.
Предоставленная пропускная способность для контейнера распределяется равномерно между физическими разделами. Дизайн ключа раздела, который не распределяет запросы равномерно, может привести к слишком большому числу запросов, направленных на небольшое подмножество разделов, которые становятся "горячими". Горячие разделы вызывают неэффективное использование выделенной пропускной способности, что может привести к ограничению скорости и более высоким затратам.
Например, рассмотрим контейнер с путем /foodGroup, указанным в качестве ключа раздела. Контейнер может иметь любое количество физических секций, но в этом примере предполагается, что он имеет три. Один физический раздел может содержать несколько ключей разделов. Например, самая большая физическая секция может содержать три наиболее значимых логических секций Beef Products: , Vegetable and Vegetable Productsи Soups, Sauces, and Gravies.
При назначении пропускной способности в 18 000 единиц запросов в секунду (ЕЗ/с) каждая из трех физических секций использует одну треть от общей подготовленной пропускной способности. В пределах выбранной физической секции ключи логических разделов Beef Products, Vegetable and Vegetable Products и Soups, Sauces, and Gravies в совокупности могут использовать 6000 подготовленных RU/с. Поскольку предоставленная пропускная способность равномерно делится между физическими разделами контейнера, важно выбрать ключ раздела, который равномерно распределит нагрузку по потреблению пропускной способности. Дополнительные сведения см. в разделе "Выбор правильного логического ключа секции".
Управление логическими разделами
Azure Cosmos DB автоматически управляет размещением логических секций на физических секциях в соответствии с потребностями масштабируемости и производительности контейнера. Когда требования к пропускной способности и хранилищу приложения увеличиваются, Azure Cosmos DB перемещает логические секции, чтобы распределить нагрузку по нескольким физическим секциям. Дополнительные сведения о физических секциях.
Azure Cosmos DB использует хэш-секционирование для распределения логических секций между физическими секциями. Azure Cosmos DB хэширует значение разделительного ключа для элемента. Хэшированные результаты определяют логический раздел. Затем Azure Cosmos DB равномерно распределяет ключевое пространство хэшей ключей разделов по физическим разделам.
Транзакции в хранимых процедурах или триггерах разрешены только для элементов в одной логической секции.
Наборы реплик
Каждая физическая секция состоит из набора реплик, который также называется набором реплик. В каждой реплике размещен экземпляр ядра СУБД. Набор реплик делает хранилище данных в физической секции устойчивым, высокодоступным и согласованным. Каждая реплика в физическом разделе наследует квоту хранилища раздела. Все реплики физической секции совместно поддерживают пропускную способность, выделенную для этой физической секции. Azure Cosmos DB автоматически управляет наборами реплик.
Для небольших контейнеров обычно требуется один физический раздел, однако у них должно быть минимум четыре реплики.
На этом рисунке показано, как логические секции сопоставляются с физическими секциями, распределенными глобально. Набор разделов в образе означает группу физических разделов, которые управляют одними и теми же ключами логических разделов в нескольких регионах.
Выберите ключ раздела
Ключ секции содержит два компонента: путь и значение. Например, рассмотрим элемент { "userId" : "Andrew", "worksFor": "Microsoft" }, если вы выбрали userId в качестве ключа секции, ниже приведены два компонента ключа секции:
Путь к ключу раздела (например, "/userId"). Путь ключа раздела принимает буквенно-цифровые символы и символы подчеркивания (_). Вы также можете использовать вложенные объекты также с помощью стандартной нотации пути (/).
Значение ключа раздела (например, "Andrew"). Значение ключа раздела может быть строкового или числового типа.
Узнайте об ограничениях на пропускную способность, хранилище и длину ключа раздела в статье о квотах службы Azure Cosmos DB.
Выбор ключа раздела — это простой, но важный элемент проектирования в Azure Cosmos DB. Выбрав ключ секции, изменить его в дальнейшем невозможно. Если вам нужно изменить ключ секции, переместите данные в новый контейнер с нужным ключом секции. Задания копирования контейнеров помогают в этом процессе. Кроме того, можно добавить глобальные вторичные индексы (предварительная версия) для создания копий данных с разными ключами секций, оптимизированными для определенных шаблонов запросов.
Для всех контейнеров ключ секции должен:
Является свойством, имеющим значение, которое не изменяется. Если свойство является ключом разбиения, его значение невозможно обновить.
Important
Значения ключа секции неизменяемы. После создания элемента его значение ключа секции не может быть изменено на месте. Операция замены элементов требует, чтобы ключ секции соответствовал существующему элементу. Его нельзя использовать для перемещения элемента между секциями. Чтобы переместить элемент, необходимо создать новый элемент с новым значением ключа секции и удалить исходный элемент. Эти две операции нельзя выполнять атомарно в разных логических разделах.
Содержат только
Stringзначения — или преобразуйте числа вString, если они могут превышать границы чисел двойной точности в соответствии со стандартом Института инженеров электротехники и электроники (IEEE) 754 binary64. Спецификация Json объясняет, почему использование чисел за пределами этой границы является плохой практикой из-за проблем взаимодействия. Эти проблемы особенно важны для столбца ключа раздела, так как он неизменяем и требует последующей миграции данных.Высокая кардинальность. Другими словами, свойство должно иметь широкий диапазон возможных значений.
Потребление единиц запроса и хранение данных должно быть равномерно распределено по всем логическим секциям. Это распределение обеспечивает равномерное потребление и распределение единиц запроса (RU) по физическим разделам.
Обычно значения не превышают 2048 байт, или 101 байт, если отключены большие ключи раздела. Дополнительные сведения см. в разделе "Большие ключи разбивки"
Если в Azure Cosmos DB требуются многокомпонентные ACID-транзакции, необходимо использовать хранимые процедуры или триггеры. Все хранимые процедуры и триггеры на основе JavaScript ограничены одной логической секцией.
Замечание
Если у вас есть только одна физическая секция, или количество секций небольшое, например <= 5, значение ключа секции может не быть соответствующим. Для запросов превышение расходов на проверку каждого дополнительного физического раздела, если ключ раздела не включен, составляет 2–3 RU для каждого физического раздела. Дополнительные сведения о физических секциях.
Типы ключей разделов
| Стратегия секционирования | Когда использовать | Преимущества | Недостатки |
|---|---|---|---|
| Обычный ключ раздела (например, CustomerId, OrderId) | Используйте, когда ключ партиции имеет высокую кардинальность и соответствует шаблонам запросов (например, фильтрация по CustomerId). Подходит для рабочих нагрузок, где запросы в основном предназначены для данных одного клиента (например, получение всех заказов для клиента). | Простое управление. Эффективные запросы, когда шаблон доступа соответствует ключу секции (например, запрашивая все заказы с помощью CustomerId). Предотвращает межсекционные запросы, если шаблоны доступа согласованы. | Риск возникновения горячих разделов, если некоторые значения (например, несколько клиентов с высоким трафиком) создают больше данных, чем другие. Может достигнуть предельного значения 20 ГБ на логическую секцию, если объем данных для определенного ключа быстро увеличивается. |
| Искусственный ключ партиционирования (например, CustomerId + OrderDate) | Используется, если ни одно поле не имеет высокой кардинальности и не соответствует шаблонам запросов. Хорошо подходит для рабочих нагрузок с большим количеством операций записи, в которых данные должны равномерно распределяться по физическим секциям (например, многие заказы, размещенные на одной дате). | Помогает равномерно распределять данные между секциями, уменьшая горячие секции (например, распределение заказов по CustomerId и OrderDate). Распределяет записи между несколькими секциями и повышает пропускную способность. | Запросы, которые фильтруют только по одному полю (например, только CustomerId), могут привести к межсекционным запросам. Запросы через несколько разделов могут привести к увеличению потребления вычислительных единиц (дополнительная плата 2-3 ВЕ/с за каждый существующий физический раздел) и увеличению задержки. |
| Иерархический ключ секции (HPK) ( например, CustomerId/OrderId, StoreId/ProductId) | Используйте при необходимости секционирования на нескольких уровнях для поддержки крупномасштабных наборов данных. Идеально подходит для фильтрации запросов на первом и втором уровнях иерархии. | Помогает избежать ограничения на 20 ГБ путем создания нескольких уровней секционирования. Эффективное выполнение запросов на обоих иерархических уровнях (например, фильтрация сначала по CustomerID, а затем по OrderID). Сводит к минимуму запросы между секциями для запросов, предназначенных для верхнего уровня (например, получение всех данных из определенного CustomerID). | Требует тщательного планирования, чтобы убедиться, что ключ первого уровня должен быть высокой кардинальности и включается в большинство запросов. Более сложным для управления, чем обычный ключ раздела. Если запросы не соответствуют иерархии (например, фильтрация только по OrderID, когда CustomerID является первым уровнем), производительность запросов может снизиться. |
| Глобальный вторичный индекс (GSI) — предварительная версия ( например, источник использует CustomerId, GSI использует OrderId) | Используйте, если не удается найти один ключ секции, который работает для всех шаблонов запросов. Идеально подходит для рабочих нагрузок, которым требуется эффективно запрашивать по нескольким независимым свойствам и иметь большое количество физических разделов. | Устраняет запросы между разделами при использовании ключа разбиения GSI. Разрешает несколько шаблонов запросов на одни и те же данные с автоматической синхронизацией из исходного контейнера. Изолирование производительности между нагрузками. | Каждая GSI имеет дополнительные затраты на хранение и RU. Данные в GSI в конечном итоге согласованы с исходным контейнером. |
Ключи партиционирования для контейнеров, ориентированных на интенсивное чтение
Для большинства контейнеров эти критерии – все, что нужно учитывать при выборе ключа разбиения. Но для больших контейнеров с высокой интенсивностью чтения может потребоваться выбрать ключ секции, который часто используется в качестве фильтра в запросах. Включение ключа секции в предикате фильтра позволяет эффективно направлять запросы только к соответствующим физическим секциям.
Это свойство является хорошим выбором ключа секции, если большинство запросов рабочей нагрузки являются запросами, и большинство запросов используют фильтр равенства для того же свойства. Например, если часто выполняется запрос c фильтрацией по UserID, то при выборе UserID в качестве ключа секции уменьшится количество запросов между секциями.
Если контейнер мал, скорее всего, у вас недостаточно физических секций, чтобы беспокоиться о производительности запросов между секциями. Большинству небольших контейнеров в Azure Cosmos DB требуется только одна или две физические секции.
Если ваш контейнер может вырасти до более чем нескольких физических секций, следует выбрать ключ распределения, который минимизирует запросы между секциями. Контейнеру требуется больше, чем несколько физических разделов, если выполняется один из следующих сценариев.
В вашем контейнере подготовлено более 30 000 единиц запросов.
Контейнер хранит более 100 ГБ данных
Глобальные вторичные индексы для запросов между секциями
Если приложению необходимо запрашивать данные с помощью нескольких различных свойств эффективно, глобальные вторичные индексы (предварительная версия) предоставляют альтернативу использованию одной стратегии ключа секции для набора данных. Глобальные вторичные индексы — это дополнительные контейнеры с разными ключами секций, автоматически синхронизированные с данными из исходного контейнера.
Учитывайте глобальные вторичные индексы, когда:
- У вас есть несколько шаблонов запросов, которые не могут быть удовлетворены одной стратегией ключа раздела.
- Изменение существующего ключа раздела вызовет перебои
- Необходимо изолировать аналитические или поисковые рабочие нагрузки от транзакционных операций
Глобальные вторичные индексы помогают избежать межсекционных запросов, сохраняя одни и те же данные с разными ключами секций, оптимизированными для определенных шаблонов запросов. Этот подход может значительно сократить потребление ресурсов и повысить производительность запросов в случаях, когда одной лишь оптимизации ключа секции недостаточно.
Используйте идентификатор элемента в качестве ключа партиции
Замечание
Этот раздел в основном относится к API для NoSQL. Другие API, такие как API для Gremlin, не поддерживают уникальный идентификатор в качестве ключа секции.
Если в контейнере есть свойство с широким диапазоном возможных значений, скорее всего это отличный выбор для разделяющего ключа. Примером такого свойства является идентификатор элемента. Для небольших контейнеров с частыми операциями чтения или контейнеров любого размера с частыми операциями записи, ID элемента (/id) естественно является отличным выбором для ключа секции.
Системное свойство идентификатор элемента присутствует в каждом элементе вашего контейнера. У вас могут быть другие свойства, представляющие логический идентификатор элемента. Во многих случаях эти уникальные идентификаторы также являются отличным выбором в качестве ключа раздела по тем же причинам, что и идентификатор элемента.
Использование идентификатора элемента в качестве ключа разбиения — удачный выбор по следующим причинам.
- Существует широкий диапазон возможных значений (один уникальный идентификатор элемента для каждого элемента).
- Так как для каждого элемента существует уникальный идентификатор элемента, идентификатор элемента выполняет большую работу при равномерном балансировке потребления единиц запросов и хранилища данных.
- Вы можете легко выполнять эффективное точечное чтение, так как вы всегда знаете ключ раздела элемента, если знаете его идентификатор.
При выборе идентификатора элемента в качестве ключа секции следует учитывать следующие предостережения:
- Если идентификатор элемента является ключом секции, он становится уникальным идентификатором для всего контейнера. Нельзя создавать элементы с повторяющимися идентификаторами.
- Если у вас есть контейнер с большим количеством физических секций, запросы эффективнее, если они имеют фильтр равенства с идентификатором элемента.
- Хранимые процедуры или триггеры не могут нацеливается на несколько логических секций.