Автоматическое шардирование и балансировка динамических таблиц

Шардирование и балансировка необходимы для равномерного распределения нагрузки по кластеру. Оно включает в себя:

Шардирование необходимо для того, чтобы таблеты у таблицы стали примерно одинакового размера. Перераспределение между таблет-селлами — чтобы на таблет-селлы приходилось примерно поровну данных и/или нагрузки. Равномерность распределения данных особенно важна для таблиц, находящихся в памяти (c @in_memory_mode отличным от none), так как память на кластере весьма ограниченный ресурс и при неудачном распределении некоторые узлы кластера могут оказаться перегружены. Равномерность нагрузки особенно важна, если нагрузка не является равномерной по ключам таблицы, а также если определенный вид нагрузки является для вашего бандла ограниченным ресурсом.

Балансировку можно настраивать как потаблично, так и для каждого таблет-селл бандла. Также балансировку можно настраивать для групп таблиц. Конфигурация на таблице приоритетнее конфигурации группы, которая, в свою очередь, приоритетнее конфигурации бандла.

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

Стратегии балансировки

  • Решардирование по размеру. Для равномерного разложения таблетов таблицы по таблет-селлам необходимо, чтобы каждый таблет был не очень большого размера. Таблеты большого размера подвергаются делению на несколько, таблеты маленького размера объединяются с соседними;
  • Решардирование по параметру и размеру (доступно только на кластерах с выделенным балансировщиком). Для равномерной балансировки по параметру необходимо, чтобы все таблеты таблицы были примерно одного размера и имели относительно одинаковую нагрузку. Таблеты с большой нагрузкой или большим размером решардируются, таблеты небольшого размера с маленькой нагрузкой подвергаются объединению с соседними;
  • Балансировка между таблет-селлами
    • Таблицы в памяти. Балансируются по размеру путем минимизации загрузки максимально загруженного селла (для таблиц с ханками — по их неханковой части). Учитывается только суммарное потребление памяти нод всеми таблицами, распределение таблетов каждой таблицы в отдельности не оптимизируется;
    • Таблицы на диске. Балансируются по количеству таблетов таблицы по таблет-селлам бандла;
  • Параметризованная балансировка между нодами (она же балансировка по нагрузке, доступна только на кластерах с выделенным балансировщиком). Минимизирует дисперсию заданной метрики по нодам и, в меньшей степени, по селлам. Потабличная равномерность не учитывается, все таблеты считаются равнозначными.

Конфигурация балансировки

Группы таблиц

Доступно только на кластерах с выделенным балансировщиком.

Для удобства конфигурации существуют группы балансировки. Их конфиги лежат в поле groups в конфиге бандла. Если такого параметра нет (автоматически он не создаётся) — его нужно создать. Внутри группы все таблицы балансируются вместе.

Как создать группу балансировки с определёнными значениями

Необходимо создать в поле groups пустой словарь, аналогично создаются конфиги для групп балансировки, подконфиги и т. д.
yt set //sys/tablet_cell_bundles/<bundle_name>/@tablet_balancer_config/groups '{}'
или создать сразу группу с нужной конфигурацией
yt set //sys/tablet_cell_bundles/<bundle_name>/@tablet_balancer_config/groups '{alpha={parameterized={max_action_count=5}; schedule="minutes % 45 == 0"}}'

Чтобы определить таблицу в группу с именем alpha, необходимо в атрибуте @tablet_balancer_config таблицы установить поле group в alpha.

Параметры конфигурации групп

Имя Тип Значение по умолчанию Описание
type legacy / parameterized legacy для групп legacy и legacy_in_memory, parameterized для остальных Тип балансировки. legacy не может быть установлен для новых групп
parameterized yson Конфигурация для параметризованной балансировки. Подробнее в разделе про конфигурацию параметризованной балансировки
schedule Арифметическая формула с использованием minutes, hours и числовыми значениями Берется из конфига бандла, если значение установлено, иначе зависит от конфигурации на кластере Расписание балансировки. В тот момент, когда формула становится истинной, запускается решардирование всех таблиц группы, а через некоторое время (типично порядка 10 минут) — перемещение между селлами. Примеры можно посмотреть в разделе с расписанием
enable_move boolean %true Разрешает перемещение между таблет-селлами. Тип балансировки зависит от группы
enable_reshard boolean %true Разрешает автоматическое решардирование. Тип балансировки зависит от группы
Пример конфигурации группы

Внимание

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

"in_memory_stable" = {
    "enable_move" = %true;
    "enable_reshard" = %true;
    "schedule" = "minutes % 30 == 5";
    "parameterized" = {
        "max_action_count" = 100;
        "metric" = "double([/statistics/memory_size])";
    };
};

Системные группы

С точки зрения балансировщика системные группы существуют по умолчанию, даже если в @tablet_balancer_config/groups не перечислены явно конфиги этих групп. Значения по умолчанию для них берутся из таблицы выше. Ниже перечислены все системные группы.

  • legacy: балансировка между таблет-селлами таблиц на диске;
  • legacy_in_memory: балансировка между таблет-селлами таблиц в памяти;
  • default: в эту группу попадают все таблицы, для которых включена параметризованная балансировка, но группа не указана явно.

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

  • на таблице явно указана группа default;
  • на таблице не указана группа, но в конфиге балансировки выставлено enable_parameterized=true;
  • на таблице явно не указана группа и на бандле включена параметризованная балансировка по умолчанию (enable_parameterized_by_default=%true).

Если в конфиге бандла указано имя группы для балансировки таблиц в памяти по умолчанию (атрибут default_in_memory_group), тогда таблицы в памяти, которые должны были быть определены в default, определяются в указанную в конфиге группу.

Потабличные настройки

Список доступных настроек для таблицы (//path/to/table/@tablet_balancer_config) приведён в таблице:

Имя Тип Значение по умолчанию Описание
enable_auto_reshard boolean %true Включение/отключение решардирования
enable_auto_tablet_move boolean %true Включение/отключение перемещения таблетов таблицы между селлами
min_tablet_size int - Минимальный размер таблета для решардирования по размеру
desired_tablet_size int - Желаемый размер таблета для решардирования по размеру
max_tablet_size int - Максимальный размер таблета для решардирования по размеру
desired_tablet_count int - Желаемое количество таблетов для решардирования
min_tablet_count int - Минимальное количество таблетов для решардирования по размеру, смотрите пояснение в тексте
group* str - Определяет таблицу в группу балансировки, подробнее смотрите в разделе Группы таблиц
enable_parameterized* boolean - Включение/отключение перемещения таблетов по нагрузке

* — доступна только на кластерах с выделенным балансировщиком

Пример конфигурации таблицы

Внимание

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

{
    "enable_auto_reshard" = %true;
    "enable_auto_tablet_move" = %true;
    "group" = "writes";

# use the rest wisely
    "enable_verbose_logging" = %false;
    "enable_parameterized" = %true;
    "desired_tablet_count" = 100;
    "min_tablet_count" = 5;
    "min_tablet_size" = 1000;
    "desired_tablet_size" = 5000;
    "max_tablet_size" = 10000;
}

Побандловые настройки

Настройки указываются в //sys/tablet_cell_bundles/<bundle_name>/@tablet_balancer_config.
Если на бандле и на таблице указаны противоречащие друг другу настройки, при балансировке будут использоваться настройки таблицы, так как их приоритет выше.

Имя Тип Значение по умолчанию Описание
min_tablet_size int 128 MB Минимальный размер таблета таблицы на диске
desired_tablet_size int 10 GB Желаемый размер таблета таблицы на диске
max_tablet_size int 20 GB Максимальный размер таблета таблицы на диске
min_in_memory_tablet_size int 512 MB Минимальный размер таблета таблицы в памяти
desired_in_memory_tablet_size int 1 GB Желаемый размер таблета таблицы в памяти
max_in_memory_tablet_size int 2 GB Максимальный размер таблета таблицы в памяти
enable_tablet_size_balancer boolean %true Включение/отключение решардирования по размеру
enable_in_memory_cell_balancer boolean %true Включение/отключение балансировки таблетов таблиц в памяти между таблет-селлами
enable_cell_balancer boolean %false Включение/отключение балансировки таблетов таблиц на диске между таблет-селлами
tablet_to_cell_ratio double 5. Решардирование по размеру ограничивает сверху количество таблетов в таблице числом таблет-селлов, умноженным на значение этого параметра
enable_parameterized_by_default* boolean %false Определение таблиц без явного указания group в группу default для параметризованной балансировки
groups* dictionary - Конфиги групп балансировки
default_in_memory_group* str - Имя группы по умолчанию для in memory таблиц для параметризованной балансировки

* — доступно только на кластерах с выделенным балансировщиком

Пример конфигурации бандла

Внимание

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

{
    "enable_cell_balancer" = %true;
    "enable_in_memory_cell_balancer" = %true;
    "enable_tablet_size_balancer" = %true;
    "min_tablet_size" = 500;
    "desired_tablet_size" = 1000;
    "max_tablet_size" = 2000;
    "min_in_memory_tablet_size" = 50;
    "desired_in_memory_tablet_size" = 100;
    "max_in_memory_tablet_size" = 1000;
    "hard_in_memory_cell_balance_threshold" = 0.15;
    "soft_in_memory_cell_balance_threshold" = 0.05;
    "tablet_balancer_schedule" = "(hours * 60 + minutes) % 80 == 10";
    "tablet_to_cell_ratio" = 5.;
    "enable_verbose_logging" = %false;
    "enable_parameterized_by_default" = %true;
    "groups" = {
        "in_memory_stable" = {
            # ... parameterized balancing only
        };
        "legacy" = {
            # ...
        };
        "default" = {
            # ... parameterized balancing only
        };
        "legacy_in_memory" = {
            # ...
        };
    };
}

Конфигурация параметризованной балансировки

Доступно только на кластерах с выделенным балансировщиком.

Имя Тип Значение по умолчанию Описание
metric str - Метрика (параметр) балансировки
max_action_count int - Максимальное количество таблетов, которые будут перемещены за одну итерацию
enable_reshard boolean - Включение алгоритма решардирования по параметру и размеру вместо решардирования по размеру

Метрика для параметризованной балансировки задается арифметической формулой с использованием потаблетных метрик. Метрика должна быть неотрицательной для любого таблета. Для корректной работы алгоритма балансировки величина метрики должна быть прямо пропорциональна нагрузке на таблет. В формуле могут участвовать метрики размеров таблетов. Каждая из метрик нагрузки может иметь один из двух суффиксов на выбор: _10m_rate и _1h_rate, которые считаются как экспоненциальное затухание запросов за 10 минут и за 1 час. В таблице все метрики приведены для 10-минутного окна.

Ниже перечислены потаблетные метрики, которые могут быть полезны.

  • Объём записи
    double([/performance_counters/dynamic_row_write_data_weight_10m_rate])
  • Количество данных, читаемых lookup-запросами
    double([/performance_counters/dynamic_row_lookup_data_weight_10m_rate]) + double([/performance_counters/static_chunk_row_lookup_data_weight_10m_rate])
  • Количество данных, читаемых select-запросами
    double([/performance_counters/dynamic_row_read_data_weight_10m_rate]) + double([/performance_counters/static_chunk_row_read_data_weight_10m_rate])
  • Uncompressed size
    double([/statistics/uncompressed_data_size])
  • Compressed size
    double([/statistics/compressed_data_size])
  • Memory size (объём данных, занимаемых таблицей в памяти; в зависимости от in_memory_mode равен либо compressed, либо uncompressed size)
    double([/statistics/memory_size])
  • CPU time, потребляемое lookup-запросами
    double([/performance_counters/lookup_cpu_time_10m_rate]) |
  • Количество таблетов (имеет смысл, если таблеты необходимо разложить по нодам поровну без учёта нагрузки)
    1

Конфигурация решардирования

Решардирование по размеру

  • Если в настройках таблицы указан параметр desired_tablet_count, то балансировщик будет пытаться шардировать таблицу на указанное число таблетов.
  • Иначе, если в настройках таблицы указаны все три параметра min_tablet_size, desired_tablet_size, max_tablet_size и их значения допустимы (т. е. выполнено min_tablet_size < desired_tablet_size < max_tablet_size), будут использоваться значения указанных параметров.
  • В противном случае будут использоваться настройки таблет-селл бандла.

Примечание

При явном указании всех трех параметров размеров таблетов (min, desired и max) для корректной работы алгоритма необходимо соблюдать следующую рекомендацию: отношение max / min должно быть как минимум 2.5, а лучше хотя бы 3. При меньших значениях отношения алгоритм не сможет достичь оптимального размера за счет решардирования и будет постоянно пытаться подогнать таблеты по размеру, тем самым мешая работе с таблицей.

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

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

Решардирование по размеру и параметру

Данный вид решардирования предназначен для совместной работы с параметризованной балансировкой. Оба алгоритма используют одну и ту же метрику (параметр), который указывается в конфиге группы балансировки. Для включения этого вида решардирования в конфиге на таблице необходимо указать желаемое количество таблетов desired_tablet_count. Без этого значения алгоритм не может предугадать желаемые значения параметра для метрики каждого таблета. Также для включения нужно выставить в %true значение флага enable_reshard в конфиге параметризованной балансировки группы.

Алгоритм похож на алгоритм решардирования по размеру за исключением условий, при которых таблеты подвергаются делению и объединению. При обнаружении таблета, который по размеру или по параметру не подходит хотя бы под одно из min/max ограничений, таблет подвергается делению или объединению с соседними, чтобы по возможности привести его к желаемым размерам и значениям параметра. Упомянутые ограничения вычисляются из желаемого количества таблетов таблицы.

Примечание

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

Отключение

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

  • Для бандла: //sys/tablet_cell_bundles/<bundle>/@tablet_balancer_config/<attribute>
  • Для группы: //sys/tablet_cell_bundles/<bundle>/@tablet_balancer_config/groups/<group>/<attribute>
  • Для таблицы: //path/to/table/@tablet_balancer_config/<attribute>
Тип балансировки Бандл Группа Таблица
in-memory move enable_in_memory_cell_balancer enable_move enable_auto_tablet_move
ordinary move enable_cell_balancer enable_move enable_auto_tablet_move
parameterized move - enable_move enable_auto_tablet_move
reshard enable_tablet_size_balancer enable_reshard enable_auto_reshard
parameterized reshard - enable_reshard enable_auto_reshard

Расписание автоматического шардирования

Шардирование неизбежно отмонтирует часть таблетов таблицы. Чтобы сделать этот процесс более предсказуемым, существует возможность настроить, в какое время должен работать балансировщик. Настройка бывает per-cluster, per-bundle и per-group.

Расписание для бандла находится в атрибуте //sys/tablet_cell_bundles//@tablet_balancer_config/tablet_balancer_schedule. Расписание для группы находится в атрибуте schedule в конфиге группы.

В качестве формата можно указать любую арифметическую формулу от целочисленных переменных hours и minutes. Балансировка таблиц бандла будет происходить только в те моменты времени, когда значение формулы истинно (т. е. отлично от нуля).

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

Примеры:

  • minutes % 20 == 0 — балансировка в 0-ю, 20-ю и 40-ю минуту каждого часа;
  • hours % 2 == 0 && minutes == 30 — балансировка в 00:30, 02:30, ...

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

Кластер Расписание
first-cluster (hours * 60 + minutes) % 40 == 0
second-cluster (hours * 60 + minutes) % 40 == 10
third-cluster (hours * 60 + minutes) % 40 == 20

Детали реализации

Балансировка перемещениями

Параметризованная балансировка

Внимание

Все таблеты группы для алгоритма являются равнозначными, распределение по таблицам не учитывается.

Балансировка применяется для таблиц, определенных в группы, отличные от legacy_in_memory и legacy.

Описание алгоритма

Алгоритм вычисляет metric для каждого таблета, дальше в зависимости от распределения таблетов по селлам и нодам вычисляются метрики по селлам и по нодам как сумма метрик таблетов на них. После пошагово минимизируется
nodeNodeMetric2+cellCellMetric2\sum_{node}{NodeMetric^2} + \sum_{cell}{CellMetric^2}

За шаг parameterized балансировки может произойти перемещение таблета с его селла на другой селл.

Алгоритм не будет запущен, если распределение и по селлам, и по нодам достаточно хорошее.

Балансировка между таблет-селлами на диске

Внимание

Все таблеты таблицы для алгоритма являются равнозначными, размеры таблетов не учитываются.

Группа балансировки: legacy

Описание алгоритма

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

Балансировка между таблет-селлами в памяти

Внимание

Все таблеты группы для алгоритма являются равнозначными, распределение по таблицам не учитывается.

Группа балансировки: legacy_in_memory

Описание алгоритма

Таблеты раскладываются равномерно на селлы бандла по memory_size. Распределение по таблицам не учитывается.

Шардирование

Решардирование по размеру

Осуществляется посредством деления таблетов и склеивания соседних. Решардирование различных таблиц производится независимо.

Описание алгоритма

Для каждой таблицы независимо алгоритм итерируется по таблетам и делит слишком большие или объединяет соседние таблеты. Таблет считается слишком большим, если его размер больше max_tablet_size. В таком случае таблет может быть разделен на несколько или поделен вместе с соседними на несколько таблетов так, чтобы размер новых таблетов был примерно desired_tablet_size. Также происходит объединение, если таблеты меньше min_tablet_size.

Если на таблице указан min_tablet_count и таблетов не более этого количества, они не будут объединены, даже если они меньше min_tablet_size. Этот параметр не влияет на min/desired/max tablet_size.

Если на таблице указан desired_tablet_count, то ограничения вычисляются как:

  • desired_tablet_size = table_size / desired_tablet_count
  • min_tablet_size = desired_tablet_size / 1.9
  • max_tablet_size = desired_tablet_size * 1.9

Для корректной работы алгоритма требуется, чтобы max_tablet_size / min_tablet_size > 2. Иначе балансер будет по циклу делать бесполезные действия, которые будут мешать работе таблицы. Остальные рекомендации по конфигурации можно посмотреть в соответствующем разделе.

Решардирование по размеру и метрике

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

Описание алгоритма

Для работы требует указания desired_tablet_count. С помощью этого значения для каждой таблицы вычисляются следующие значения:

  • desired_tablet_size = table_size / desired_tablet_count
  • min_tablet_size = desired_tablet_size / 1.9
  • max_tablet_size = desired_tablet_size * 1.9
  • desired_tablet_metric = table_metric / desired_tablet_count
  • min_tablet_metric = desired_tablet_metric / 1.9
  • max_tablet_metric = desired_tablet_metric * 1.9

Алгоритм итерируется по таблетам и делит слишком большие или объединяет соседние таблеты. Таблет считается слишком большим, если его размер больше max_tablet_size или метрика больше max_tablet_metric. В таком случае таблет может быть разделен на несколько так, чтобы новые таблеты укладывались в заданные ограничения. Алгоритм поделит слишком большой таблет даже в том случае, если его значение по оставшемуся параметру меньше желаемого. Объединение происходит в том случае, если таблет меньше min_tablet_size или min_tablet_metric.

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