Управление бандлами динамических таблиц
В YTsaurus есть возможность гибкого управления бандлами динамических таблиц. Для каждого бандла можно задавать количество таблетных нод, распределение числа потоков по пулам потоков и памяти по категориям. В случае отказа ноды автоматика назначит бандлу новую ноду из запаса.
Обзор
Система, управляющая бандлами, называется Bundle controller. Она управляет инстансами таблетных нод. Каждая нода привязана к некоторому бандлу или находится в запасе. Каждый бандл и каждый инстанс относится к определённой зоне — набору инстансов с общим запасом. В настоящее время поддерживается только одна зона zone_default
.
Bundle controller выставляет на каждый бандл атрибут node_tag_filter
, имеющий вид zone_default/<bundle_name>
. Также это значение устанавливается в атрибут user_tags
всех нод, выданных бандлу. Каждая нода может принадлежать не более чем одному бандлу. В случае отказа ноды Bundle controller автоматически выдаёт бандлу новую ноду.
Для каждого бандла есть возможность указать его конфигурацию: число таблетных нод, число таблет-целлов на каждой ноде, распределение памяти по категориям и количество потоков в некоторых пулах потоков. Этими настройками можно управлять через пользовательский интерфейс на странице бандла.
Также Bundle controller управляет аккаунтами, в которых хранятся журналы и снапшоты таблет-целлов бандла.
Первоначальная настройка
Для упрощения настройки типичного сценария подготовлен скрипт bundle_controller_tools.py. Рекомендуется запускать его с флагом --init-all
. При запуске необходимо указать флаги --cpu
и --memory
, соответствующие параметрам инстансов таблетных нод. Если в кластере есть инстансы разных размеров, рекомендуется выставлять параметры по минимальному инстансу.
В дальнейших разделах описаны шаги по настройке, выполняемые скриптом.
Системные директории
При запуске bundle_controller_tools.py
системные директории создаются автоматически. Для пропуска этого шага можно использовать флаг --no-init-system-directories
.
Для начала эксплуатации Bundle controller необходимо создать следующие директории:
//sys/bundle_controller/coordinator
//sys/bundle_controller/controller/zones/zone_default
//sys/bundle_controller/controller/bundles_state
Также необходимо создать аккаунт с названием bundle_system_quotas
.
Зона zone_default
Для автоматической настройки зоны необходимо запустить bundle_controller_tools.py
с флагом --init-default-zone
.
Инстансы каждого типа привязаны к некоторому бандлу или находятся в запасе. Каждый бандл и инстанс относится к определённой зоне. В конфиге зоны необходимо указать размер инстансов (CPU и RAM), имеющихся в кластере, а также настройки по умолчанию для пулов потоков и категорий памяти нод.
Внимание
В настоящее время Bundle controller может работать только с кластерами, в которых все инстансы одного размера. Это значит, что поле resource_guarantee
в конфиге зоны, конфигах всех бандлов и аннотациях всех таблетных нод должно принимать одно и то же значение.
Если в кластере есть инстансы разных размеров, рекомендуется выставлять resource_guarantee
по минимальному инстансу.
Конфиг зоны находится по пути //sys/bundle_controller/controller/zones/zone_default
. Каждое поле конфига является атрибутом указанной директории.
Таблетные ноды
Конфигурация таблетных нод указывается в атрибуте tablet_node_sizes
. Это словарь, состоящий из одного поля regular
(тип инстанса). Он имеет следующий вид:
{
"default_config" = {
"cpu_limits" = {
"lookup_thread_pool_size" = 8;
"write_thread_pool_size" = 10;
"query_thread_pool_size" = 8;
};
"memory_limits" = {
"tablet_dynamic" = 1000000;
"versioned_chunk_meta" = 1000000;
"uncompressed_block_cache" = 200000;
"tablet_static" = 0;
"compressed_block_cache" = 1000000;
"reserved" = 5000000;
"lookup_row_cache" = 0;
};
};
"resource_guarantee" = {
"net_bytes" = 0;
"vcpu" = 6000;
"memory" = 1073741824;
};
}
Здесь default_config
— это распределение пулов потоков и категорий памяти по умолчанию для всех бандлов, а resource_guarantee
— размер инстанса таблетной ноды. Поле memory
соответствует размеру RAM в байтах, поле vcpu
соответствует числу ядер CPU контейнера, умноженному на 1000. Поле net_bytes
в настоящий момент не используется.
Подробнее о распределении пулов потоков и категорий памяти см. раздел Создание бандла.
RPC proxy
Примечание
В текущей версии управление RPC proxy поддержано не полностью.
Конфигурация RPC proxy указывается в атрибуте rpc_proxy_sizes
. Это словарь, состоящий из одного поля regular
(тип инстанса). Он имеет следующий вид:
{
"resource_guarantee" = {
"net_bytes" = 0;
"vcpu" = 6000;
"memory" = 1073741824;
};
}
Значения полей имеют тот же смысл, что и в случае таблетных нод.
Аннотации инстансов
Для автоматической настройки инстансов необходимо запустить bundle_controller_tools.py
с флагом --init-tablet-nodes
.
Все таблетные ноды, находящиеся под управлением Bundle controller, должны быть размечены определёнными атрибутами. Атрибуты подробно описаны в разделе Добавление нод в кластер.
Настройка бандлов
Для автоматической настройки бандлов необходимо запустить bundle_controller_tools.py
с флагом --init-bundle <bundle-name>
, --init-all-bundles
или --init-all
.
Чтобы Bundle controller начал управлять существующими бандлами, необходимо установить на них атрибуты, указанные в разделе Создание бандла. Если на существующих бандлах был установлен атрибут node_tag_filter
, его необходимо предварительно установить в значение ""
(пустая строка).
Скрипт bundle_controller_tools.py
вычисляет необходимое число нод для каждого существующего бандла по текущему количеству таблет-целлов. В случае, если необходимо выдать больше или меньше нод, используйте аргумент --bundle-node-count
, принимающий на вход yson-словарь в формате {<bundle_name>=<node_count>}
.
Аккаунты под журналы и снапшоты
Для автоматической настройки бандлов необходимо запустить bundle_controller_tools.py
с флагом --init-bundle-system-quotas
или --init-all
.
Bundle controller может управлять аккаунтами, в которых хранятся журналы и снапшоты таблет-целлов. Аккаунты управляются полями changelog_account
и snapshot_account
в опциях бандла в атрибуте //sys/tablet_cell_bundles/<bundle_name>/@options
. Аккаунты, находящиеся под управлением Bundle controller, имеют название <bundle_name>_bundle_system_quotas
и являются дочерними для корневого аккаунта bundle_system_quotas
. Bundle controller автоматически регулирует квоты родительского и дочерних аккаунтов в случае изменения числа таблет-целлов.
В статическом конфиге Bundle controller в секции bundle_controller
есть поля, регулирующие объём ресурсов, необходимый для одного таблет-целла:
node_count_per_cell
: число нод Кипарисаchunk_count_per_cell
: число чанковjournal_disk_space_per_cell
: объём дискового пространства для журналовsnapshot_disk_space_per_cell
: объём дискового пространства для снапшотовmin_node_count
: минимальное число нод Кипариса, выдаваемое бандлуmin_chunk_count
: минимальное число чанков, выдаваемое бандлу
Создание бандла
Для создания бандла можно использовать скрипт bundle_controller_tools.py
с флагом --create-bundle <bundle_name>
.
Чтобы бандл оказался под управлением Bundle controller, на нём должны быть установлены атрибуты enable_bundle_controller = %true
и zone = "zone_default"
. Также должен быть установлен атрибут bundle_controller_target_config
, имеющий следующий вид:
{
"cpu_limits" = {
"lookup_thread_pool_size" = 2;
"query_thread_pool_size" = 2;
"write_thread_pool_size" = 2;
};
"memory_limits" = {
"tablet_dynamic" = 1000000;
"tablet_static" = 0;
"compressed_block_cache" = 1000000;
"uncompressed_block_cache" = 200000;
"versioned_chunk_meta" = 1000000;
"lookup_row_cache" = 0;
"reserved" = 5000000;
};
"rpc_proxy_count" = 0;
"rpc_proxy_resource_guarantee" = {
"memory" = 1073741824;
"net_bytes" = 0;
"vcpu" = 6000;
};
"tablet_node_count" = 1;
"tablet_node_resource_guarantee" = {
"memory" = 1073741824;
"net_bytes" = 0;
"vcpu" = 6000;
};
}
Поля имеют следующее значение:
tablet_node_count
: число таблетных нод, выданных бандлу.tablet_node_resource_guarantee
: размер инстанса таблетных нод, выданных бандлу. Должен совпадать со значением в конфиге зоны.rpc_proxy_count
: число RPC proxy, выданных бандлу. В настоящий момент не поддерживается.rpc_proxy_resource_guarantee
: размер инстанса RPC proxy, выданных бандлу. Должен совпадать со значением в конфиге зоны. В настоящий момент не поддерживается.memory_limits
: распределение категорий памяти таблетных нод бандла. Суммарное значение должно быть не больше, чемmemory
вresource_guarantee
.tablet_dynamic
: буфер памяти под dynamic stores.tablet_static
: память под in-memory таблицы (сin_memory_mode
отличным отnone
).compressed_block_cache
,uncompressed_block_cache
: кеши для блоков с данными, используемые при чтении.versioned_chunk_meta
: кеш метаинформации о чанках.lookup_row_cache
: память под построчный кеш.reserved
: память, зарезервированная под системные нужды и неучтённые категории.
cpu_limits
: распределение потоков таблетных нод бандла по пулам потоков. В отличие от памяти, здесь возможен оверкоммит, и число потоков может превосходитьvcpu/1000
вresource_guarantee
.lookup_thread_pool_size
: число потоков под lookup-запросы.query_thread_pool_size
: число потоков под select-запросы.write_thread_pool_size
: число таблет-целлов на ноду.
Также необходимо установить поля cpu
и memory
в атрибуте resource_limits
бандла. Суммарные vcpu
и memory
инстансов бандла не могут превосходить значений cpu*1000
и memory
из resource_limits
. Подробнее об этом написано в разделе Квотирование ресурсов.
Добавление нод в кластер
После добавления инстансов в кластер необходимо разметить их атрибутом bundle_controller_annotations
. Для этого можно использовать скрипт bundle_controller_tools.py
с флагом --init-tablet-nodes
.
Атрибут bundle_controller_annotations
имеет следующий вид:
{
"allocated" = %true;
"allocated_for_bundle" = "spare";
"resources" = {
"vcpu" = 6000;
"memory" = 1073741824;
"type" = "regular";
};
}
Здесь поле allocated
означает, что инстанс находится под управлением Bundle controller, поле allocated_for_bundle = "spare"
означает, что инстанс находится в запасе и не относится ни к какому бандлу, а поле resources
содержит ресурсы инстанса и должно совпадать с полем resource_guarantee
в соответствующей секции настройки зоны.
Вывод нод из эксплуатации
Для того чтобы вывести ноду из эксплуатации, необходимо выставить атрибут //sys/cluster_nodes/<node_address>/@cms_maintenance_requests
в значение {maintenance={}}
. После этого Bundle controller плавно перенесёт все таблет-целлы с этой ноды на другую ноду, выданную из запаса. После того как на выводимой ноде не останется таблет-целлов, её можно безопасно отключать. Наличие таблет-целлов отображается в атрибуте tablet_slots
.
В случае аварийного отказа ноды Bundle controller выдаст бандлу новую ноду из запаса, после чего на ней восстановятся таблет-целлы.
Квотирование ресурсов
Ресурсы бандла расположены в атрибуте //sys/tablet_cell_bundles/<bundle_name>/@resource_limits
. Атрибут содержит следующие поля:
tablet_count
: ограничение на число таблетов таблиц бандла.tablet_static_memory
: ограничение на суммарный размер in-memory таблиц бандла. Устанавливается автоматически.cpu
: ограничение на суммарное значениеcpu
нод бандла.memory
: ограничение на суммарное значениеmemory
нод бандла.
Поля tablet_count
и tablet_static_memory
влияют на таблицы, создаваемые в бандле. Поля cpu
и memory
влияют на число таблетных нод, которое Bundle controller может выдать бандлу.
Поле tablet_static_memory
автоматически устанавливается Bundle controller. Его значение вычисляется как node_count * memory
, где node_count
— это число нод, выданных бандлу, а memory
— количество памяти на инстансе таблетной ноды, определённое в конфиге зоны.
Для управления ресурсами необходимо право write
на бандл. Управление ресурсами должно производиться администратором кластера. Следует выдавать квоты на число нод так, чтобы суммарная квота всех бандлов не превосходила число нод в кластере с учётом запаса на случай отказа нод.
Для упрощения настройки ограничений cpu
и memory
в скрипте bundle_controller_tools.py
есть команда set-bundle-resource-limits
, которая принимает ограничение на число нод и устанавливает лимиты в соответствии с конфигом зоны.
Управление бандлом
Для управления бандлом используется кнопка Edit bundle
на странице бандла в пользовательском интерфейсе. Интерфейс позволяет указать число нод, разбивку памяти по категориям и число потоков в пулах потоков для lookup- и select-запросов.
Для управления бандлом необходимо право manage
на бандл.
Отключение Bundle controller
Для перевода Bundle controller в read-only режим необходимо установить атрибут //sys/@disable_bundle_controller
в значение %true
. Bundle controller перестанет выполнять какие-либо действия с кластером, однако состояние бандлов по-прежнему можно будет наблюдать в пользовательском интерфейсе.
Решение проблем
Bundle controller не работает
- Проверьте атрибут
//sys/@disable_bundle_controller
. - Проверьте наличие блокировок на узле
//sys/bundle_controller/coordinator/lock/@locks
. Отсутствие блокировок означает, что Bundle controller не может зарегистрироваться на кластере. Часто причины указаны в error-логе контейнера.
Failed
В интерфейсе бандла наблюдается состояние В интерфейсе бандла есть отображаются два статуса: Health
— это состояние таблет-целлов, State
— состояние Bundle controller. В случае, если State
находится в состоянии Failed
, по нажатию на состояние отображается возникшая ошибка. В некоторых случаях это состояние может быть вызвано нарушениями инвариантов Bundle controller (например, в случае несовпадения resource_guarantee
в настройках зоны, нод и бандлов). Рекомендуются следующие шаги:
- отключить Bundle controller путём установки атрибута
//sys/@disable_bundle_controller
в значение%true
; - запустить команду
bundle_controller_tools.py drop-allocations <bundle_name>
. Эта команда удалит некорректные запросы на выдачу нод; - убедиться, что конфигурация корректна (например, путём запуска
bundle_controller_tools.py init --init-all --cpu <cpu_guarantee> --memory <memory_guarantee>
).