Workload Manager — управление потреблением ресурсов
- Создание пула ресурсов
- Пул ресурсов по умолчанию
- Управление ACL пула ресурсов
- Создание классификатора пула ресурсов
- Управление ACL классификатора пула ресурсов
- Порядок выбора классификатора пула ресурсов в случае конфликтов
- Пример приоритетного пула ресурсов
- Явный выбор пула ресурсов для запроса
- Диагностика
- См. также
Пулы ресурсов позволяют изолировать ресурсы баз данных между выполняемыми запросами или же настраивать стратегии распределения ресурсов в случае переподписки (запроса большего объёма ресурсов, чем доступно в системе). Все пулы ресурсов являются равноправными, без какой-либо иерархии, и влияют друг на друга только при общем дефиците ресурсов.
Например, одним из типовых сценариев изоляции ресурсов является разделение двух классов потребителей:
- Регулярный роботный процесс, который раз в сутки строит отчёт.
- Аналитики, которые выполняют ad hoc запросы.
Важно
Представленная функциональность для управления потреблением ресурсами находится в стадии Preview.
Создание пула ресурсов
В примере ниже приведён синтаксис для создания отдельного пула ресурсов с именем "olap", в котором будут выполняться аналитические запросы:
CREATE RESOURCE POOL olap WITH (
CONCURRENT_QUERY_LIMIT=10,
QUEUE_SIZE=1000,
DATABASE_LOAD_CPU_THRESHOLD=80,
TOTAL_CPU_LIMIT_PERCENT_PER_NODE=70
)
Ознакомиться с полным перечнем параметров пулов ресурсов можно в справке по Параметры. Часть параметров является глобальными для всей базы данных (например, CONCURRENT_QUERY_LIMIT, QUEUE_SIZE, DATABASE_LOAD_CPU_THRESHOLD), а другие — применяются только к одному вычислительному узлу (например, TOTAL_CPU_LIMIT_PERCENT_PER_NODE).

Рассмотрим на примере выше, что на самом деле означают эти параметры и как они будут влиять на распределение ресурсов. Допустим, в базе данных YDB выделено узлов по . В сумме в такой базе данных . Тогда на каждом узле для пула ресурсов с именем olap будет выделено:
В сумме, при равномерном распределении ресурсов на всю базу данных, пулу ресурсов будет выделено:
Как работает CONCURRENT_QUERY_LIMIT и QUEUE_SIZE
Допустим, в пуле ресурсов olap уже выполняются 9 запросов. При поступлении нового запроса он сразу начнёт выполняться параллельно с другими 9-ю запросами. Теперь в пуле будет работать 10 запросов. Если в пул поступит 11-й запрос, он не начнёт выполняться, а будет помещён в очередь ожидания. Когда хотя бы один из 10 выполняющихся запросов завершится, 11-й запрос будет извлечён из очереди и начнёт выполняться.
Если в очереди уже находится запросов, то при отправке 1001-го запроса клиент сразу же получит в ответ ошибку, и этот запрос не будет выполнен. Пример ошибки:
Issues:
<main>: Error: Request was rejected, number of local pending requests is 20, number of global delayed/running requests is 0, sum of them is larger than allowed limit 1 (including concurrent query limit 1) for pool olap
<main>: Error: Query failed during adding/waiting in workload pool olap
На число параллельно выполняемых запросов влияет не только CONCURRENT_QUERY_LIMIT, но и DATABASE_LOAD_CPU_THRESHOLD.
Как работает DATABASE_LOAD_CPU_THRESHOLD
Когда запрос поступает в пул ресурсов, для которого установлен DATABASE_LOAD_CPU_THRESHOLD, сразу резервируется 10% от доступного CPU на узле, исходя из предположения, что запрос как минимум потребует такой объём ресурсов. Затем каждые 10 секунд происходит перерасчёт потребляемых ресурсов по всей базе данных, что позволяет уточнить первоначальную 10%-ную оценку. Это означает, что если на узел кластера одновременно поступит более 10 запросов, то не более 10 запросов будут запущены на выполнение, а остальные будут ожидать уточнения фактического потребления CPU.
Как и в случае CONCURRENT_QUERY_LIMIT, при превышении указанного порога нагрузки запросы отправляются в очередь ожидания.
Пул ресурсов по умолчанию
Даже если ни одного пула ресурсов не было создано, в системе всегда существует пул ресурсов default, который не может быть удалён. Любой запрос, выполняющийся в системе, всегда принадлежит какому-либо пулу — ситуации, когда запрос не привязан ни к одному пулу ресурсов, не бывает. По умолчанию настройки пула ресурсов default выглядят следующим образом:
CREATE RESOURCE POOL default WITH (
CONCURRENT_QUERY_LIMIT=-1,
QUEUE_SIZE=-1,
DATABASE_LOAD_CPU_THRESHOLD=-1,
TOTAL_CPU_LIMIT_PERCENT_PER_NODE=-1
)
Это означает, что в пуле ресурсов default не применяются никакие ограничения: он функционирует независимо от других пулов и не имеет ограничений на потребляемые ресурсы. В пуле ресурсов default можно изменять параметры с помощью запроса ALTER RESOURCE POOL, за исключением параметров CONCURRENT_QUERY_LIMIT, DATABASE_LOAD_CPU_THRESHOLD и QUEUE_SIZE. Это ограничение введено намеренно, чтобы минимизировать риски, связанные с некорректной настройкой пула ресурсов по умолчанию.
Управление ACL пула ресурсов
Права на создание, изменение, удаление пула ресурсов
Для создания, изменения или удаления пула ресурсов необходимо выдать права доступа в соответствии с разрешениями, описанными в справке по CREATE RESOURCE POOL. Например, для создания пулов ресурсов нужно иметь разрешение CREATE TABLE на директорию .metadata/workload_manager/pools, которое можно выдать запросом следующего вида:
GRANT CREATE TABLE ON `.metadata/workload_manager/pools` TO user1;
Права на выполнение запроса в пуле ресурсов
Чтобы выполнить запрос в пуле, пользователь должен иметь право доступа SELECT на этот пул. Пример выдачи прав:
GRANT SELECT
ON `.metadata/workload_manager/pools/olap`
TO `user1@domain`;
Создание классификатора пула ресурсов
Классификаторы пулов ресурсов позволяют задавать правила, по которым запросы будут распределяться между пулами ресурсов. В примере ниже приведён классификатор пула ресурсов, который отправляет запросы от всех пользователей в пул ресурсов с именем olap:
CREATE RESOURCE POOL CLASSIFIER olap_classifier
WITH (
RESOURCE_POOL = 'olap',
MEMBER_NAME = 'all-users@well-known'
);
RESOURCE_POOL— имя пула ресурсов, в который будет отправлен запрос, удовлетворяющий требованиям, заданным в классификаторе пула ресурсов.MEMBER_NAME— группа пользователей или пользователь, запросы которых будут отправлены в указанный пул ресурсов. Подробнее о формате значения см. CREATE RESOURCE POOL CLASSIFIER.
Управление ACL классификатора пула ресурсов
Классификаторы пула ресурсов глобальны для всей базы данных и применяются ко всем пользователям. Для создания, удаления или изменения классификатора пула ресурсов необходимо иметь право доступа USE на всю базу данных, которое можно выдать запросом вида:
GRANT USE ON `/my_db` TO user1;
Важно
Для использования классификатора у пользователя должен быть доступ к пулу ресурсов, на который этот классификатор ссылается. Если такого доступа нет, классификатор пропускается и проверяется следующий. В будущих версиях это поведение может быть изменено, поэтому не используйте отсутствие прав на пул как механизм управления тем, какой классификатор сработает.
Порядок выбора классификатора пула ресурсов в случае конфликтов
CREATE RESOURCE POOL CLASSIFIER olap1_classifier
WITH (
RESOURCE_POOL = 'olap1',
MEMBER_NAME = 'user1@domain'
);
CREATE RESOURCE POOL CLASSIFIER olap2_classifier
WITH (
RESOURCE_POOL = 'olap2',
MEMBER_NAME = 'user1@domain'
);
Допустим, имеются два классификатора пулов ресурсов с конфликтующими условиями, и пользователь user1@domain подходит под оба пула ресурсов: olap1 и olap2. Если до этого в системе не существовало ни одного классификатора, то для olap1 устанавливается RANK=1000, а для olap2 — RANK=2000. Классификаторы пулов ресурсов с меньшим значением RANK имеют более высокий приоритет. В данном примере, так как у olap1 более приоритетный RANK, чем у olap2, будет выбран именно он.
Также можно самостоятельно задавать RANK для классификаторов пулов ресурсов при создании с помощью синтаксической конструкции CREATE RESOURCE POOL CLASSIFIER, либо изменять RANK для существующих классификаторов пулов ресурсов с помощью ALTER RESOURCE POOL CLASSIFIER.
В системе не может существовать два классификатора с одинаковым значением RANK, что позволяет однозначно определить, какой пул ресурсов будет выбран в случае конфликтующих условий.
Пример приоритетного пула ресурсов
Рассмотрим пример разделения ресурсов между командой аналитиков и условным директором (CEO). Важно, чтобы запросы CEO продолжали выполняться даже тогда, когда аналитические задачи загружают базу данных. Конфигурация для этого сценария может выглядеть следующим образом:
CREATE RESOURCE POOL olap WITH (
CONCURRENT_QUERY_LIMIT=20,
QUEUE_SIZE=100,
DATABASE_LOAD_CPU_THRESHOLD=80,
TOTAL_CPU_LIMIT_PERCENT_PER_NODE=100
);
CREATE RESOURCE POOL the_ceo WITH (
CONCURRENT_QUERY_LIMIT=20,
QUEUE_SIZE=100,
TOTAL_CPU_LIMIT_PERCENT_PER_NODE=100
);
В примере выше создаются два пула ресурсов: olap для команды аналитиков и the_ceo для CEO.
- Пул ресурсов
olap:DATABASE_LOAD_CPU_THRESHOLD=80означает, что при достижении загрузки CPU базы данных в 80% новые аналитические запросы перестают запускаться и ожидают в очереди, вмещающей доQUEUE_SIZE=100запросов. - Пул ресурсов
the_ceo: параметрDATABASE_LOAD_CPU_THRESHOLDне задан, поэтому запросы CEO продолжают запускаться независимо от степени загрузки базы данных.
Это обеспечивает CEO приоритет при перегрузке: пул аналитики ограничивается первым, а пул CEO — нет.
Важно
Этот механизм управляет только моментом запуска запросов. Он не резервирует CPU для одного пула за счёт другого, пока запросы уже выполняются: оба пула выше ограничены значением TOTAL_CPU_LIMIT_PERCENT_PER_NODE=100, поэтому выполняющиеся запросы конкурируют за CPU на равных условиях.
Явный выбор пула ресурсов для запроса
При необходимости пользователь может явно указать, в каком пуле следует выполнить заданный запрос. В настоящий момент это можно сделать следующим образом:
- YDB UI — в окне настройки запуска запроса
Query execution settingsчерез параметрResource pool. - YDB CLI — в команде
ydb sqlс параметром--resource-pool, например,ydb sql --resource-pool my_pool -s "SELECT 1". - YDB CLI (интерактивный режим) — командой
SET resource_pool = my_pool, гдеmy_pool— наименование пула ресурсов. - YDB CPP SDK — в настройках запуска запроса через параметр ResourcePool.
- YDB GO SDK — в настройках запуска запроса
ExecuteOptionчерез вызов WithResourcePool. - YDB Java SDK — в настройках запуска запроса
ExecuteQuerySettingsчерез вызов withResourcePool, начиная с версии 2.3.12. - YDB Python SDK — в параметре pool_id методов
QuerySession.execute(),QueryTxContext.execute()иQuerySessionPool.execute_with_retries(), начиная с версии 3.31.2.
Диагностика
План запроса
Подробную информацию о планах запросов можно найти на странице структура планов запросов. Для получения информации об используемом пуле ресурсов необходимо запустить команду с получением статистики в формате json-unicode. Пример команды:
ydb -p <profile_name> sql -s 'select 1' --stats full --format json-unicode
В теле плана запроса, полученного с помощью приведённой выше команды, можно найти полезные атрибуты для диагностики работы с пулом ресурсов. Пример такой информации:
"Node Type" : "Query",
"Stats" : {
"TotalDurationUs": 28795,
"ProcessCpuTimeUs": 45,
"Compilation": {
"FromCache": false,
"CpuTimeUs": 7280,
"DurationUs": 21700
},
"ResourcePoolId": "default",
"QueuedTimeUs": 0
},
"PlanNodeType" : "Query"
Полезные атрибуты:
TotalDurationUs— общее время выполнения запроса, включая время ожидания в очереди.ResourcePoolId— имя пула ресурсов, к которому был привязан запрос.QueuedTimeUs— общее время ожидания запроса в очереди.
Статус выполняющегося запроса
Информацию о том, как обрабатывается запрос в Workload Manager, можно получить на основе системного представления .sys/query_sessions. В этом представлении есть следующие поля:
WmPoolId(Utf8)- Идентификатор пула, в котором выполняется запрос.WmState(Utf8)- Статус запроса в WM.WmEnterTime(Timestamp)- Время, когда запрос перешел в статус PENDING или DELAYED.WmExitTime(Timestamp)- Время, когда запрос передан на выполнение.
Возможные значения поля WmState:
NONE- Не обрабатывается.PENDING- Обрабатывается (в процессе классификации/маршрутизации).DELAYED- В очереди.EXITED- Передан на исполнение.
Следующий запрос выводит информацию обо всех активных запросах в системе:
select
Query, -- Запрос
WmPoolId, -- Идентификатор пула
WmState, -- Статус запроса в WM
WmEnterTime, -- Время, когда запрос перешел в статус PENDING или DELAYED
WmExitTime -- Время, когда запрос передан на выполнение
from `.sys/query_sessions`
where State = 'EXECUTING'
Метрики
Информацию о метриках пулов ресурсов можно найти в справке по метрикам.
Системные представления
Информацию о системных представлениях, связанных с пулами ресурсов и классификаторами пулов ресурсов, можно найти на странице Информация о пулах ресурсов.