Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Вы можете разделить хранилище данных на несколько горизонтальных секций, которые называются сегментами. Такой подход может повысить масштабируемость при хранении и доступе к большим объемам данных.
Контекст и проблема
Хранилище данных на одном сервере имеет следующие ограничения:
Место в хранилище: Хранилище данных для масштабируемого облачного приложения может содержать большой объем данных, которые со временем растут. Сервер предоставляет ограниченное количество дискового хранилища, и вы можете заменить существующие диски большими или добавить больше дисков по мере роста томов данных. Система в конечном итоге достигает предела, в котором невозможно увеличить емкость хранилища на одном сервере.
Вычислительные ресурсы: Облачное приложение должно поддерживать большое количество одновременных пользователей, которые выполняют запросы к хранилищу данных. Один сервер может не обеспечить достаточно вычислительной мощности для этой нагрузки, что приводит к расширенным времени отклика и времени ожидания. Вы можете добавить память или модернизировать процессоры, но система достигает предела, после которого невозможно увеличить вычислительные ресурсы.
Пропускная способность сети: Скорость, с которой один сервер может получать запросы и отправлять ответы, ограничивает производительность хранилища данных. Объем сетевого трафика может превышать емкость сетевого подключения, что приводит к сбою запросов.
География: Для хранения данных пользователей в том же географическом регионе, что и пользователи, могут потребоваться требования законодательства, соответствия или производительности. Если пользователи охватывают страны или регионы, возможно, вы не сможете хранить все данные приложения в одном хранилище данных.
Чтобы временно отложить эти ограничения, можно вертикально масштабировать, добавив емкость диска, мощность обработки, память и сетевые подключения. Облачное приложение, которое должно поддерживать большое количество пользователей и больших объемов данных, должно масштабироваться горизонтально.
Решение
Вы можете разделить хранилище данных на горизонтальные секции (сегменты). Каждый сегмент имеет одинаковую схему, но содержит свою собственную часть данных. Каждый сегмент — это полное хранилище данных, которое может содержать данные для многих сущностей различных типов. Шард выполняется на сервере, который работает в качестве узла хранилища.
Такой подход связан со следующими преимуществами:
Вы можете масштабировать систему, добавив дополнительные сегменты на дополнительные узлы хранилища.
Система может использовать предварительно созданное оборудование, а не специализированные и дорогие компьютеры для каждого узла хранилища.
можно минимизировать конфликты и повысить производительность, правильно распределяя рабочую нагрузку между сегментами;
В облаке сегменты могут физически находиться рядом с пользователями, обращающимися к данным.
При делении хранилища данных на сегменты решите, какие данные следует размещать в каждом сегменте. Каждый сегмент обычно содержит элементы, сгруппированные по одному или нескольким атрибутам данных. Эти атрибуты формируют ключ шарда, иногда называемый ключом партиции.
Сегментирование определяет физическую структуру данных. Когда приложение хранит и извлекает данные, логика сегментирования направляет ее в соответствующий сегмент. Эту логику можно реализовать в коде доступа к данным приложения или в системе хранилища данных, если она прозрачно поддерживает сегментирование.
Абстрагирование физического расположения данных в логике сегментирования обеспечивает контроль над тем, какие сегменты содержат данные. Вы также можете перенести данные между шардами, не изменяя бизнес-логику приложения, когда необходимо распределить данные, например, когда шарды становятся несбалансированными. Компромисс — это дополнительные затраты на доступ к данным, чтобы определить расположение каждого элемента данных во время извлечения.
Выбор шард-ключа
Ключ шардирования является наиболее важным решением в проектировании в сегментированной системе. Чтобы изменить ключ сегмента после выбора, обычно необходимо перенести все данные в новый макет сегментов, который является дорогостоящей и рискоемой операцией в динамической системе. Прежде чем писать любой код, сделайте это решение тщательно.
Эффективный ключ шарда является неизменяемым, имеет высокую кардинальность, распределяет данные и нагрузку равномерно, а также соответствует доминирующим шаблонам запросов, чтобы большинство запросов разрешалось в одном шарде. Избегайте монотонно возрастающих значений (автоинкрементируемых целых чисел и последовательных отметок времени), атрибутов с низкой кардинальностью (булевых и небольших наборов перечислений) и изменяющихся атрибутов, которые часто меняются. Эти атрибуты приводят к горячим точкам или дорогостоящим перемещению данных между сегментами.
Если один атрибут не соответствует этим критериям, определите составной ключ сегментирования путем объединения двух или более атрибутов. Если запросы должны извлекать данные по атрибутам, которые не являются частью shard key, используйте, например, шаблон таблицы индекса для предоставления вторичных обращений.
Дополнительные сведения о выборе ключей секций в службах Azure см. в руководстве по секционированием данных и стратегиях секционирования данных.
Стратегии шардинга
Используйте одну из следующих стратегий при выборе ключа сегментов и выборе способа распределения данных между сегментами. Вам не нужно однозначное соответствие между сегментами и серверами, на которых они размещаются. Один сервер может хостить несколько шардов.
Стратегия шардинга для поиска
В стратегии подстановки, которая также называется стратегией на основе каталогов, логика сегментирования реализует карту, которая направляет запрос данных в сегмент, содержащий эти данные с помощью ключа сегментирования. В мультитенантном приложении можно хранить все данные для клиента вместе в сегменте с помощью идентификатора клиента в качестве ключа сегмента. Несколько клиентов могут совместно использовать один сегмент, но данные для одного клиента не распределяются по нескольким сегментам. На следующей схеме показан шардинг данных арендаторов на основе идентификаторов арендаторов.
Сопоставление значений ключей шардирования и физического хранилища может быть прямым, где каждое значение ключа шардирования сопоставляется с физическим разделом. Более гибким способом является секционирование виртуальных сегментов, где значения ключей сегментов сопоставляют с виртуальными сегментами, а затем система сопоставляет эти виртуальные сегменты с меньшим количеством физических секций. Приложение находит данные с помощью значения ключа сегмента, которое ссылается на виртуальный сегмент, а система прозрачно сопоставляет виртуальные сегменты с физическими секциями. Сопоставление между виртуальным сегментом и физической секцией может изменяться, не требуя изменения кода приложения.
Стратегия сегментирования на основе диапазона
Стратегия на основе диапазона группирует связанные элементы вместе в одном сегменте и упорядочивает их по последовательному ключу сегмента. Эта стратегия поддерживает приложения, которые часто получают наборы элементов с помощью запросов диапазона. Запросы диапазона возвращают набор элементов данных для ключа сегментов, который попадает в заданный диапазон.
Например, если приложению регулярно нужно найти все заказы, размещенные в определенном месяце, данные можно получить быстрее, если хранить все заказы в течение месяца в порядке даты и времени в одном сегменте. Если вы храните каждый заказ в другом сегменте, приложение должно получать их по отдельности, выполняя большое количество точечных запросов. На следующей схеме показаны последовательные наборы или диапазоны данных, хранящихся в сегментах.
В этом примере ключ сегментов является составным ключом, который содержит месяц заказа в качестве наиболее важного элемента, за которым следует день заказа и время. Новые заказы автоматически сортируются по мере их создания и добавления в шард.
Некоторые хранилища данных поддерживают двухкомпонентные ключи шардирования. Ключ секции определяет сегмент, а ключ строки однозначно идентифицирует элемент в сегменте. Шард обычно хранит данные в порядке ключей строк. Для элементов, требующих диапазонных запросов и которые должны группироваться вместе, можно использовать шард-ключ, имеющий то же значение для ключа секции, но уникальное значение для ключа строки.
Стратегия сегментирования на основе хэша
Стратегия на основе хэша снижает вероятность хот-точек, которые являются сегментами, которые получают непропорциональное количество нагрузки. Эта стратегия распределяет данные по сегментам, чтобы сбалансировать размер каждого сегмента и среднюю нагрузку, с которой сталкивается каждый сегмент. Логика сегментирования вычисляет, в каком сегменте хранить каждый элемент данных, по значению хэш-индекса по одному или нескольким атрибутам данных. Выбранная функция хэширования должна равномерно распределять данные по сегментам. На следующей схеме показано шардирование данных арендаторов на основе хэша идентификаторов арендаторов.
Чтобы понять преимущество хэш-стратегии по сравнению с другими стратегиями сегментирования, рассмотрим, как мультитенантное приложение, которое регистрирует новых клиентов последовательно, может назначать клиентам сегменты в хранилище данных. При использовании стратегии диапазона данные для клиентов 1 – n хранятся в сегменте A, данные для клиентов n+1 до m хранятся в сегменте B, а более поздние диапазоны клиентов сопоставляются с последовательными сегментами. Если последние зарегистрированные клиенты также являются наиболее активными, большинство действий данных происходит в нескольких сегментах, что может привести к горячим точкам. В отличие от этого, стратегия хэширования выделяет клиентов сегментам на основе хэша идентификатора клиента. Хэш обычно распределяет последовательные клиенты по разным сегментам, что балансирует нагрузку. На предыдущей схеме показан этот подход для клиентов 55 и 56.
Стратегия географического сегментирования
Географическая стратегия назначает данные сегментам на основе географического происхождения или предполагаемого региона потребления этих данных. Во многих рабочих нагрузках пользователи и создаваемые ими данные сосредоточены в определенных регионах. Нормативные требования, такие как законы о местонахождении данных, могут потребовать, чтобы конкретные данные оставались в определенной юрисдикции. Даже без нормативных драйверов размещение данных близко к пользователям, которым он обращается, чаще всего снижает задержку сети для операций чтения и записи.
Ключ сегмента в этой стратегии вы определяете на основе географического атрибута, такого как страна или регион пользователя, регион исходного центра обработки данных или региональный идентификатор арендатора. Вы размещаете каждый сегмент или закрепляете его в инфраструктуре в пределах этой географической границы.
Например, приложение, которое обслуживает клиентов в Северной Америке, Европе и Asia-Pacific может поддерживать три группы сегментов, по одной группе в каждом соответствующем регионе Azure. Европейское приложение, которое обслуживает только европейских пользователей, направляет запрос в сегмент Европы. Этот подход снижает задержку и соответствует требованиям к месту расположения данных.
Географическое сегментирование представляет риск неравномерного распределения данных. Если большинство ваших пользователей находятся в одном регионе, шард этого региона несет несоразмерную часть нагрузки и объем хранения. Вы можете объединить географическое сегментирование с другой стратегией, например хэшом или поиском, в каждом регионе для равномерного распределения нагрузки между несколькими сегментами внутри одной географической границы.
Преимущества и рекомендации для каждой стратегии
Четыре стратегии сегментирования имеют следующие преимущества и рекомендации.
Стратегия поиска обеспечивает больший контроль над конфигурацией шардов. Виртуальные сегменты снижают влияние перебалансирования, так как можно добавить новые физические секции для балансировки рабочей нагрузки. Можно изменить сопоставление между виртуальным сегментом и его физическими секциями, не затрагивая код приложения. Поиск расположений шардов добавляет накладные расходы.
Стратегия диапазона легко реализуется и хорошо работает с запросами диапазона. Запросы диапазона могут извлекать несколько элементов данных из одного сегмента в одной операции. Управление данными проще. Например, можно запланировать обновления для каждого часового пояса на основе локальных шаблонов нагрузки, когда пользователи в одном регионе делят шард. Однако эта стратегия не балансирует нагрузку равномерно между сегментами. Перебалансировка трудна и не разрешает неравномерную нагрузку, когда большая часть действий сосредоточена на смежных ключах сегментов.
Стратегия хэша предоставляет более высокую вероятность равномерного распределения данных и нагрузки. Запросы можно направлять напрямую с помощью хэш-функции, не поддерживая карту. Вычисление хэша добавляет некоторые издержки. Перебалансирование трудно без согласованного хэширования.
Географическая стратегия соответствует требованиям к местоположению и суверенитету данных, которые другие стратегии изначально не учитывают. Это снижает задержку чтения и записи при доступе пользователей к данным в регионе. Однако географическое сегментирование может создавать значительные данные и дисбаланс нагрузки, если население пользователей равномерно не распределяется по регионам. Запросы, охватывающие регионы, такие как глобальные отчеты, должны извлекать данные из всех географических сегментов и получать более высокую задержку. Объедините географическое сегментирование с другой стратегией в каждом регионе, если требуется соответствие требованиям и даже распределение нагрузки.
Большинство систем сегментирования реализуют один из этих подходов, но следует также учитывать бизнес-требования приложения и его шаблоны использования данных. Например, в мультитенантном приложении:
Данные можно сегментировать на основе рабочей нагрузки. Разделяйте данные для высоковолатильных арендаторов в отдельных шардах, чтобы улучшить скорость доступа к данным для других клиентов.
Данные можно сегментировать на основе расположения клиента. Перевести данные арендатора в определенном географическом регионе в автономный режим для резервного копирования и обслуживания в течение нерабочих часов в этом регионе, в то время как данные арендатора в других регионах остаются в сети в течение их рабочих часов.
Назначьте высокоценным арендаторам собственные выделенные, мало нагруженные сегменты. Клиенты с более низким значением могут совместно использовать более плотно упакованные сегменты.
Храните данные для клиентов, которым требуется надежная изоляция данных и конфиденциальность на отдельных серверах.
Операции масштабирования и перемещения данных для каждой стратегии
Каждая стратегия шардирования предоставляет различные возможности и уровни сложности для управления масштабированием в одну сторону, масштабированием в другую сторону, перемещением данных и обслуживанием состояния.
Стратегия поиска позволяет выполнять операции масштабирования и перемещения данных на уровне пользователя как в сети, так и в автономном режиме. Для перемещения данных:
Приостановьте некоторые или все действия пользователей, как правило, во время непиковых периодов.
Переместите данные в новую виртуальную секцию или физический сегмент.
Обновите сопоставления.
Отмените или обновите все кэши, в которые хранятся эти данные.
Возобновление действия пользователя.
Эту операцию часто можно централизованно управлять. Стратегия поиска требует, чтобы данные были высоко кэшируемыми и удобными для репликации.
Стратегия диапазона ограничивает операции масштабирования и перемещения данных, так как необходимо разделить и объединить данные между сегментами, как правило, в то время как часть или все хранилище данных находится в автономном режиме. При перемещении данных для перебалансировки сегментов вы можете не устранить неравномерную нагрузку, если большая часть активности сосредоточена на соседних ключах сегментов или идентификаторах данных в одном и том же диапазоне. Стратегия диапазонов также может потребовать состояния для сопоставления диапазонов с физическими секциями.
Стратегия хэширования усложняет операции масштабирования и перемещения данных. Ключи разбиения - это хэши ключей сегментации или идентификаторов данных. При использовании стандартной хэш-функции, например
hash(key) mod Nдобавление или удаление сегмента переназначает большинство ключей и активирует масштабную миграцию данных. Согласованное хэширование уменьшает это влияние, упорядочив хэш-пространство таким образом, чтобы только небольшая часть ключей перемещалась при изменении количества сегментов. Для хэш-стратегии не требуется поддержка отдельного состояния отображения.Географическая стратегия напрямую связывает операции масштабирования с региональной подготовкой инфраструктуры. Добавление емкости в одном регионе не снижает нагрузку в другом регионе. Нормативные требования, требующие географического сегментирования, также могут ограничивать перемещение данных по географическим границам. В каждом регионе масштабирование использует вторичную стратегию, которая распределяет данные по сегментам этого региона.
Проблемы и рекомендации
Учитывайте следующие моменты при принятии решения о том, как реализовать этот шаблон.
Используйте сегментирование, дополняющее другие формы секционирования, например вертикальное секционирование и функциональное секционирование. Например, один сегмент может содержать секционированные по вертикали сущности и реализовать функциональную секцию в виде нескольких сегментов. Дополнительные сведения см. в разделе "Горизонтальное, вертикальное и функциональное секционирование данных".
Балансируйте шарды, чтобы все они могли обрабатывать аналогичный объем ввода-вывода (I/O). С течением времени данные накапливаются при вставке и удалении записей, что приводит к горячим точкам. Периодически запланируйте перебалансировку.
Перебалансирование перемещает данные между сегментами и часто приводит к простою или снижению пропускной способности. Для менее частого перераспределения используйте виртуальные разделы. Сопоставить многие логические секции с меньшим количеством физических сегментов. При перегрузке шарда перераспределите его виртуальные секции на новые физические шарды без повторного рехеширования всего набора данных. Azure Cosmos DB использует этот подход для разделения схемы секционирования от физической инфраструктуры.
Предпочтительнее много небольших шардов вместо нескольких крупных. Более мелкие сегменты переносятся быстрее, балансируют нагрузку и обеспечивают большую гибкость для распространения данных.
Используйте для ключа шарда стабильные данные. Если ключ сегмента изменяется, может потребоваться переместить соответствующий элемент данных между сегментами, что увеличивает нагрузку на операции обновления. Избегайте использования ключа сегментации, основанного на потенциально изменяющейся информации. Выберите атрибуты, которые являются инвариантными или естественно образуют ключ.
Обеспечьте уникальность значений для ключа сегмента. Например, в качестве ключа шардирования нежелательно использовать поля с автоприращением. В некоторых системах автоинкрементируемые поля не могут координироваться между шардами, что может привести к тому, что элементы в разных шардах имеют одинаковый ключ шард.
Замечание
Автоматическое увеличение значений в других полях, которые не являются шард-ключами, также может вызвать проблемы. Например, если вы используете автоматически добавочные поля для создания уникальных идентификаторов, два разных элемента в разных сегментах могут быть назначены одному и тому же идентификатору.
Сегментирование данных для поддержки наиболее часто выполняемых запросов. Возможно, вы не сможете разработать ключ сегментов, соответствующий требованиям каждого запроса к данным. При необходимости создайте таблицы вторичных индексов для поддержки запросов, которые извлекают данные по атрибутам, не входящим в ключ сегментов. Дополнительные сведения см. в разделе "Шаблон таблицы индекса".
Создайте ключ сегментов и модель данных, чтобы большинство операций были ограничены одним сегментом. Запросы, обращаюющиеся только к одному сегменту, более эффективны, чем запросы, которые извлекают данные из нескольких сегментов. Денормализуйте данные, чтобы хранить связанные сущности, которые обычно запрашиваются вместе, такие как клиенты и их заказы, в одном шарде и сократить число отдельных чтений.
Запросы между сегментами добавляют задержку, потребление ресурсов и сложность. Когда приложению необходимо получить данные из нескольких шардов, используйте параллельные фан-аут запросы, которые выполняются для каждого шарда одновременно и агрегируют результаты. Даже с параллелизмом самый медленный сегмент определяет общую задержку.
Подсказка
Если сущность в одном сегменте ссылается на сущность в другом сегменте, включите ключ сегмента для второй сущности в рамках схемы для первой сущности. Такой подход может повысить производительность запросов, ссылающихся на связанные данные между сегментами.
Пересматривайте ключ сегментов или соответствует ли сегментирование вашим потребностям, если рабочая нагрузка требует строгой целостности транзакций через границы сегментов. Транзакции между шардами создают трудности. Распределенные протоколы координации, такие как двухфазная фиксация завершения, увеличивают задержку, вводят режимы сбоев и снижают пропускную способность. Большинство сегментированных систем избегают распределенных транзакций и принимают в конечном итоге согласованность. В этой модели каждый сегмент обновляется независимо, а приложение обрабатывает временные несоответствия.
Убедитесь, что ресурсы, доступные каждому узлу хранилища шардов, могут обрабатывать требования в отношении масштабируемости с точки зрения размера и пропускной способности данных. Дополнительные сведения см. в стратегиях секционирования данных.
Возможно, стоит реплицировать ссылочные данные во все сегменты. Если запрос к сегменту также ссылается на статические или медленно перемещаемые данные, добавьте эти данные в сегмент. Затем приложение может получить все данные для запроса, не выполняя круговую поездку в отдельное хранилище данных.
Замечание
Если ссылочные данные, содержащиеся в нескольких сегментах, изменяются, система должна синхронизировать эти изменения во всех сегментах. При выполнении этой синхронизации может возникнуть некоторая степень несоответствия. Проектируйте ваши приложения так, чтобы они могли справляться с этой несогласованностью.
Сегментированные системы умножают рабочее бремя. Запланируйте следующие проблемы:
Мониторинга: Чтобы получить полное представление о работоспособности системы, необходимо агрегировать метрики и журналы во всех сегментах.
Резервное копирование и восстановление: Для обеспечения согласованности между сегментами необходимо создать резервную копию каждого сегмента независимо и создать процедуры восстановления. Восстановление одного шарда на заданный момент времени может создавать несоответствия с другими шардами.
Изменения схемы: Необходимо координировать изменения языка определения данных (DDL) на каждом сегменте.
Эти задачи можно реализовать с помощью сценариев или других решений автоматизации.
Вы можете геолокационировать сегменты, чтобы разместить их данные рядом с экземплярами приложения, которые используют его. Этот подход может повысить производительность, но требует дополнительного планирования операций, которые должны обращаться к нескольким сегментам в разных расположениях.
Когда следует использовать этот шаблон
Подсказка
Прежде чем разрабатывать пользовательский уровень сегментирования, определите, какие обязанности по сегментированиям уже обрабатываются платформой данных. Некоторые службы полностью управляют сегментированием. Например, Azure Cosmos DB распределяет данные между физическими секциями, обрабатывает разделение и маршрутизирует запросы без участия приложения. Другие службы управляют сегментированием частично. Например, база данных SQL Azure предоставляет средства эластичной базы данных для управления картами сегментов и маршрутизации, зависящей от данных, но вы разрабатываете ключ сегментов и управляете операциями разделения. Используйте шаблон сегментирования при сборке и работе логики сегментирования самостоятельно.
Используйте этот шаблон, когда:
Общий объем данных превышает емкость хранилища одного экземпляра базы данных, а параметр вертикального масштабирования не устраняет нехватку.
Пропускная способность транзакций или параллелизм запросов превышает возможности одного экземпляра справляться с ними, и наличие только реплик для чтения недостаточно для разрешения этой проблемы, поскольку нагрузка на запись также очень высока.
Замечание
Сегментирование повышает производительность и масштабируемость системы, а также повышает доступность. Сбой в одной секции не обязательно препятствует приложению получать доступ к данным в других разделах. Оператор может выполнять обслуживание или восстановление одной секции, не делая все данные недоступными. Дополнительные сведения см. в руководстве по секционированием данных.
Требования к нормативным или нормативным требованиям предписывают, что определенные подмножества данных находятся в определенных географических юрисдикциях, и ни однорегионное развертывание не может соответствовать всем требованиям.
Для отдельных клиентов или сегментов клиентов требуется физическая изоляция данных для обеспечения безопасности, производительности или договорных причин.
В таких сценариях шаблон сегментирования иногда применяется за пределами традиционных хранилищ данных. Например, система управления зонами DNS может быть сегментирована командой, средой или регионом, чтобы уменьшить радиус взрыва изменений DNS и установить четкие границы владения. В этом контексте основная мотивация — это сегментация операций, а не масштабируемость. Дополнительные сведения см. в разделе "Сегментирование частных зон DNS".
Шардинг вводит значительную и постоянную сложность в архитектуру ваших данных. Эта сложность влияет на разработку, операции, тестирование, проектирование запросов и восстановление сбоев в течение всего времени существования системы.
Этот шаблон может быть не подходит, если:
Объем данных и пропускная способность соответствуют одному экземпляру базы данных, даже при прогнозируемом росте. Вертикальное масштабирование сохраняет простоту запросов и целостность транзакций.
Узким местом является объем операций чтения, а не объем операций записи или емкость хранилища. Реплики чтения и уровни кэширования могут разгружать трафик чтения без сложностей межшардовых запросов, которые вносит шардирование.
Ядро СУБД поддерживает секционирование на уровне таблицы, соответствующее вашим потребностям в производительности. Секционирование в одном экземпляре не требует нескольких серверов или логики маршрутизации.
Для преобладающих шаблонов запросов требуются соединения между сущностями, транзакции с несколькими сущностями или полное агрегирование данных. Шардинг делает эти операции дорогостоящими, а затраты на фан-аут запросы и распределенную координацию могут перевесить преимущества масштабирования.
Проектирование рабочей нагрузки
Оцените, как использовать шаблон сегментирования в проектировании рабочей нагрузки для решения целей и принципов, описанных в основных принципах Azure Well-Architected Framework. В следующей таблице приведены рекомендации по использованию этого шаблона для целей каждого компонента.
| Столп | Как этот шаблон поддерживает цели основных компонентов |
|---|---|
| Решения по проектированию надежности помогают рабочей нагрузке стать устойчивой к сбоям и гарантировать, что она восстанавливается до полнофункционального состояния после сбоя. | Данные и обработка изолированы от сегмента, поэтому сбой в одном сегменте остается изолированным для этого сегмента. - Секционирование данных - RE:07 Самосохранение |
| Оптимизация затрат фокусируется на поддержании и улучшении окупаемости ваших инвестиций в рабочие процессы. | Система, реализующая сегменты, часто получает преимущества от использования нескольких экземпляров менее дорогих вычислительных ресурсов или ресурсов хранилища, а не одного более дорогого ресурса. Во многих случаях эта конфигурация может сэкономить деньги. - CO:07 Стоимость компонентов |
| Эффективность производительности помогает рабочей нагрузке эффективно соответствовать требованиям путем оптимизации масштабирования, данных и кода. | При использовании сегментирования в стратегии масштабирования данные и обработка изолированы для каждого сегмента, поэтому запросы конкурируют только за ресурсы в назначенном сегменте. Вы также можете использовать сегментирование для оптимизации на основе географического региона. - Pe:05 Масштабирование и секционирование - Производительность данных PE:08 |
Если этот шаблон вводит компромиссы внутри столпа, рассмотрите их против целей других столпов.
Пример
Рассмотрим веб-сайт, который представляет расширяемую коллекцию информации о опубликованных книгах по всему миру. Количество возможных книг, каталогированных в этой рабочей нагрузке, и типичные шаблоны запросов и использования превышают то, что может обрабатывать одна реляционная база данных. Архитектор рабочей нагрузки решает шардировать данные по нескольким экземплярам базы данных, используя неизменный ISBN книг в качестве ключа шардирования. В частности, архитектор использует контрольную цифру (0 – 10) ISBN, которая предоставляет 11 возможных логических сегментов с достаточно сбалансированным распределением данных.
Для начала архитектор размещает 11 логических шардов в три физические базы данных шардов. В этом подходе к виртуальному разделению многие логические разделы соотносятся с меньшим количеством физических узлов. Архитектор использует подход шардирования lookup и сохраняет сопоставление "ключ — сервер" в базе данных карты шардирования.
Служба приложений Azure помечена веб-сайтом каталога книг. Он подключается к нескольким экземплярам базы данных SQL и к экземпляру службы поиска ИИ Azure. Одна из баз данных помечена как база данных ShardMap. Она содержит пример таблицы, которая отражает часть таблицы сопоставления, которая приведена далее в этой статье. Таблица включает три экземпляра баз данных шардов: bookdbshard0, bookdbshard1 и bookdbshard2. Другие базы данных включают идентичные примеры списков таблиц под ними. К таблицам относятся Books, LibraryOfCongressCatalog и индикатор наличия других таблиц. ИИ-поиск используется для фасетной навигации и поиска по сайту. Управляемое удостоверение ассоциировано со службой приложений Azure.
Карта сегментов шардирования
База данных карты сегментов содержит следующую таблицу сопоставления сегментов и данные.
SELECT ShardKey, DatabaseServer
FROM BookDataShardMap
| ShardKey | DatabaseServer |
|----------|----------------|
| 0 | bookdbshard0 |
| 1 | bookdbshard0 |
| 2 | bookdbshard0 |
| 3 | bookdbshard1 |
| 4 | bookdbshard1 |
| 5 | bookdbshard1 |
| 6 | bookdbshard2 |
| 7 | bookdbshard2 |
| 8 | bookdbshard2 |
| 9 | bookdbshard0 |
| 10 | bookdbshard1 |
Пример кода веб-сайта: доступ к одному сегменту
Веб-сайт не знает, сколько физических баз данных сегментов существует (три в данном случае) или логика, которая сопоставляет ключ сегментов с экземпляром базы данных. Он знает только, что контрольная цифра ISBN книги является ключом шарда. Веб-сайт имеет доступ только для чтения к базе данных карты сегментов и доступ на чтение и запись ко всем базам данных сегментов. В этом примере веб-сайт использует управляемое системой удостоверение узла службы приложений Azure для авторизации, что позволяет не хранить секреты в строках подключения.
Веб-сайт настраивается с использованием следующих строк подключения в appsettings.json файле, как показано в этом примере, или с помощью параметров службы приложений App Service.
{
...
"ConnectionStrings": {
"ShardMapDb": "Data Source=tcp:<database-server-name>.database.windows.net,1433;Initial Catalog=ShardMap;Authentication=Active Directory Default;App=Book Site v1.5a",
"BookDbFragment": "Data Source=tcp:SHARD.database.windows.net,1433;Initial Catalog=Books;Authentication=Active Directory Default;App=Book Site v1.5a"
},
...
}
В следующем коде показано, как веб-сайт запускает запрос на обновление для пула сегментов базы данных рабочей нагрузки.
...
// All data for this book is stored in a shard based on the book's ISBN check digit,
// which is converted to an integer 0 - 10 (special value 'X' becomes 10).
int isbnCheckDigit = book.Isbn.CheckDigitAsInt;
// Establish a pooled connection to the database shard for this specific book.
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: isbnCheckDigit, cancellationToken))
{
// Update the book's Library of Congress catalog information.
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = @"UPDATE LibraryOfCongressCatalog
SET ControlNumber = @lccn,
...
Classification = @lcc
WHERE BookID = @bookId";
cmd.Parameters.AddWithValue("@lccn", book.LibraryOfCongress.Lccn);
...
cmd.Parameters.AddWithValue("@lcc", book.LibraryOfCongress.Lcc);
cmd.Parameters.AddWithValue("@bookId", book.Id);
await cmd.ExecuteNonQueryAsync(cancellationToken);
}
...
В предыдущем примере кода, если book.Isbn было 978-8-1130-1024-6, isbnCheckDigit то должно быть 6. Вызов OpenShardConnectionForKeyAsync(6) обычно реализуется с помощью подхода с кешированием вне потока. Если данные кэшированных сегментов для ключа сегментов 6 недоступны, метод запрашивает базу данных карты сегментов, определяемую строкой ShardMapDb подключения. Метод извлекает значение bookdbshard2 из кэша приложения или базы данных сегментов и заменяет его SHARD в строке BookDbFragment подключения. Затем метод устанавливает или повторно возвращает пуловое подключение к bookdbshard2.database.windows.net, открывает его и возвращает его в вызывающий код. Затем код обновляет существующую запись в этом экземпляре базы данных.
Пример кода веб-сайта: доступ к нескольким сегментам
В редких случаях, когда требуется прямой, кросс-шардовый запрос, приложение выполняет параллельный расширенный запрос на всех сегментах для веб-сайта.
...
// Retrieve all shard keys.
var shardKeys = shardedDatabaseConnections.GetAllShardKeys();
// Run the query in a fan-out style against each shard in the shard list.
Parallel.ForEachAsync(shardKeys, async (shardKey, cancellationToken) =>
{
using (SqlConnection sqlConn = await shardedDatabaseConnections.OpenShardConnectionForKeyAsync(key: shardKey, cancellationToken))
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = @"SELECT ...
FROM ...
WHERE ...";
SqlDataReader reader = await cmd.ExecuteReaderAsync(cancellationToken);
while (await reader.ReadAsync(cancellationToken))
{
// Collect the results into a thread-safe data structure.
}
reader.Close();
}
});
...
В качестве альтернативы запросам между сегментами эта рабочая нагрузка может использовать внешний индекс в службе "Поиск ИИ Azure" для поиска сайтов или фасетной навигации.
Добавление экземпляров шардов
Команда рабочей нагрузки знает, что если каталог данных или его параллельное использование значительно растет, они могут потребовать более трех экземпляров базы данных. Команда не ожидает динамического добавления серверов баз данных и принимает перерыв в работе, когда новый сегмент становится доступным. Чтобы создать новый экземпляр сегментов в сети, они должны переместить данные из существующих сегментов в новый сегмент и обновить таблицу карты сегментов. С помощью этого довольно статического подхода рабочая нагрузка может уверенно кэшировать сопоставление базы данных ключей сегментов в коде веб-сайта.
Логика ключа сегментов в этом примере имеет верхний предел в 11 физических сегментов. Если команда рабочей нагрузки определяет, что по оценке нагрузки им в конечном итоге требуется более 11 экземпляров базы данных, они должны внести инвазивные изменения в логику шард-ключа. Это изменение включает в себя тщательное планирование изменений кода и миграции данных в новую логику ключа.
Функциональные возможности пакета SDK
Вместо написания пользовательского кода для управления сегментами и маршрутизации запросов к экземплярам базы данных SQL оцените клиентскую библиотеку эластичной базы данных. Эта библиотека поддерживает управление картами сегментов, маршрутизацию запросов, зависящих от данных, и меж сегментные запросы в C# и Java.
Следующий шаг
- Уровни согласованности в Azure Cosmos DB. Распределение данных между сегментами представляет компромиссы согласованности. В этой статье описывается спектр моделей согласованности, от строгой до конечной, а также их влияние на доступность и задержку.
Связанные ресурсы
- Горизонтальное, вертикальное и функциональное секционирование данных. В этой статье описываются другие стратегии секционирования данных в облаке для повышения масштабируемости, уменьшения количества разных данных и оптимизации производительности.
- Шаблон таблицы индексов. Иногда невозможно поддерживать все запросы только с помощью проектирования ключа шардирования. Приложение может использовать шаблон таблицы индекса для получения данных из большого хранилища данных, указав ключ, отличный от ключа сегментов.
- Шаблон материализованного представления: для поддержания производительности некоторых операций запроса можно создавать материализованные представления, которые агрегируют и суммируют данные, особенно если распределять эти данные по сегментам.