CREATE RESOURCE POOL CLASSIFIER
CREATE RESOURCE POOL CLASSIFIER создаёт классификатор пулов ресурсов.
Синтаксис
CREATE RESOURCE POOL CLASSIFIER <name>
WITH ( <parameter_name> [= <parameter_value>] [, ... ] )
name— имя создаваемого классификатора пула ресурсов. Должно быть уникальным. Имя не должно содержать символы, запрещённые для схемных объектов.WITH ( <parameter_name> [= <parameter_value>] [, ... ] )— позволяет задавать значения параметров, определяющих поведение классификатора пула ресурсов.
Общие параметры
RANK(Int64) — опциональное поле, задающее порядок выбора классификатора пула ресурсов. Если значение не указано, берётся максимальный существующийRANKи к нему прибавляется 1000. Допустимые значения: уникальное число в диапазоне .RESOURCE_POOL(String) — имя пула ресурсов, в который направляются запросы, удовлетворяющие предикатам классификатора.ACTION(Enum) — действие, применяемое к запросу при срабатывании классификатора. Допустимое значение —reject: запрос отклоняется, пользователь получает ошибку видаRequest is rejected by classifier '<name>' (rank=<rank>).
Примечание
Параметры RESOURCE_POOL и ACTION взаимоисключающие: в классификаторе должен быть указан ровно один из них.
Параметры-предикаты
Предикат — условие, проверяемое для входящего запроса. Классификатор срабатывает, если выполнены все его предикаты (логическое AND). Для реализации логики OR необходимо создать несколько классификаторов с разными значениями RANK. Классификаторы обрабатываются в порядке возрастания RANK; обработка останавливается на первом сработавшем — к запросу применяется его ACTION или он направляется в его RESOURCE_POOL.
Параметры-предикаты необязательны. Классификатор без предикатов срабатывает на любой запрос — это удобно для «закрывающего» классификатора с максимальным RANK, например, направить весь неклассифицированный трафик в конкретный пул (RESOURCE_POOL) или отклонить его (ACTION='reject').
Важно
Будьте внимательны при создании «закрывающего» классификатора: все классификаторы, следующие за ним по RANK, никогда не сработают — обработка останавливается на первом совпадении, а «закрывающий» срабатывает всегда.
Список предикатов:
MEMBER_NAME(String) — SID пользователя или группы, от имени которых поступил запрос. Подробнее — ниже.HAS_PATH(String) — путь к объекту YDB, к которому обращается запрос; поддерживает подстановочные знаки*и?. Подробнее — ниже.HAS_APP_NAME(String) — идентификатор клиентского приложения. Подробнее — ниже.HAS_FULL_SCAN(String) — путь к объекту, по которому ожидается полное сканирование; поддерживает подстановочные знаки*и?. Подробнее — ниже.HAS_STREAM(Bool) — признак стримингового запроса. Подробнее — ниже.
MEMBER_NAME
MEMBER_NAME сравнивается посимвольно с SID пользователя или любым SID группы из его токена аутентификации. Формат SID зависит от того, каким способом пользователь пришёл в систему.
- Встроенные пользователи YDB (логин/пароль) — SID совпадает с именем пользователя, без суффикса. Например,
user1. Подробнее — Аутентификация по логину и паролю. - Облачные пользователи (Access Service) — SID имеет вид
<subject_id>@as, где<subject_id>— идентификатор пользователя в IAM. Суффикс задаётся параметромaccess_service_domain(по умолчаниюas). Например,ajeb89hv69nujke769fa@as. Подробнее — Аутентификация с использованием стороннего IAM-провайдера. - LDAP — SID имеет вид
<логин>@<домен>, где домен задаётся параметромldap_authentication_domain(по умолчаниюldap). Например,user1@ldap. Подробнее — Аутентификация с использованием LDAP-каталога. - Внешние провайдеры идентификации (OIDC) — SID имеет вид
<логин>@<домен>, где домен задаётся параметромexternal_idp_authentication_domainв конфигурации аутентификации (по умолчаниюsso). Например,user1@sso.
В качестве значения можно указать как SID конкретного пользователя, так и SID группы. Ко всем аутентифицированным пользователям автоматически добавляется группа all-users@well-known — её удобно использовать, если нужно направить в пул запросы от всех аутентифицированных клиентов.
Пример. Направить запросы пользователя user1@ldap в пул olap:
CREATE RESOURCE POOL CLASSIFIER cl_user WITH (
RANK=100,
RESOURCE_POOL='olap',
MEMBER_NAME='user1@ldap'
);
HAS_PATH
HAS_PATH сравнивает пути объектов YDB, к которым обращается запрос, с указанной маской. Маска поддерживает подстановочные знаки: * — любая последовательность символов, ? — один любой символ. Предикат срабатывает, если хотя бы один объект в плане запроса соответствует маске.
Пример. Направить запросы к архивным таблицам в пул pool_archive:
CREATE RESOURCE POOL CLASSIFIER cl_archive WITH (
RANK=700,
RESOURCE_POOL='pool_archive',
HAS_PATH='/Root/db/archive/*'
);
HAS_APP_NAME
HAS_APP_NAME сравнивает значение с идентификатором клиентского приложения. Значение передаётся клиентом в метаданных gRPC-запроса через заголовок x-ydb-application-name; SDK YDB предоставляют способ задать его на стороне клиента. Сравнение — на точное совпадение (без подстановочных знаков).
Важно
Значение HAS_APP_NAME задаётся клиентом и не аутентифицируется сервером — не используйте его как средство контроля доступа. Для эффективной изоляции сочетайте с MEMBER_NAME или направляйте нераспознанные запросы в sandbox-пул с жёсткими лимитами.
Установка идентификатора приложения в клиенте:
- YDB UI — фиксированное значение
ydb-ui, задаётся YDB UI и не настраивается пользователем. - YDB CLI — не поддерживается: идентификатор клиентского приложения в запросе не отправляется.
- YDB C++ SDK — на каждом запросе через параметр
HeaderнастроекTRequestSettings:settings.Header({{ NYdb::YDB_APPLICATION_NAME, "my-app" }}), где константаYDB_APPLICATION_NAMEравнаx-ydb-application-name. - YDB Go SDK — на драйвере через опцию
WithApplicationNameв вызовеydb.Open. - YDB Java SDK — на транспорте через метод
GrpcTransportBuilder.withApplicationName. - YDB Python SDK — отдельного параметра нет; значение задаётся на каждом запросе через дополнительный заголовок:
settings.with_header("x-ydb-application-name", "my-app")(методBaseRequestSettings.with_header).
Пример. Направить запросы от YDB UI в пул pool_adhoc:
CREATE RESOURCE POOL CLASSIFIER cl_adhoc_ui WITH (
RANK=200,
RESOURCE_POOL='pool_adhoc',
HAS_APP_NAME='ydb-ui'
);
HAS_FULL_SCAN
HAS_FULL_SCAN определяет запросы, содержащие полное сканирование указанных объектов. Полное сканирование — чтение таблицы без ограничения по ключу или диапазону ключей. Аргумент — маска пути к объекту с поддержкой подстановочных знаков * и ?; предикат срабатывает, если в плане запроса есть хотя бы один такой объект. Поддерживаются как строковые, так и колоночные таблицы. Объекты, к которым понятие полного сканирования неприменимо (например, топики), не учитываются.
Особенности определения полного сканирования:
-
LIMITне отменяет полное сканирование. Без условия по ключу формируется физический план, обрабатывающий всю таблицу целиком;LIMITограничивает только размер результата. -
Вторичные индексы. Полное сканирование индексной таблицы вторичного индекса засчитывается по её собственному пути. Например, у таблицы
CREATE TABLE orders ( Id Uint64 NOT NULL, Status Utf8, PRIMARY KEY (Id), INDEX by_status GLOBAL ON (Status) );индексная таблица имеет путь
/Root/orders/by_status/indexImplTable. ЗапросSELECT * FROM orders VIEW by_statusвыполняет полное сканирование именно индексной таблицы — основная/Root/ordersне сканируется. Поэтому:HAS_FULL_SCAN='/Root/orders'— не сработает;HAS_FULL_SCAN='/Root/orders/by_status/indexImplTable'илиHAS_FULL_SCAN='/Root/orders/*'— сработает.
Пример. Отклонять запросы, вызывающие полное сканирование архива заказов:
CREATE RESOURCE POOL CLASSIFIER cl_fullscan_reject WITH (
RANK=100,
ACTION='reject',
HAS_FULL_SCAN='/Root/db/orders_archive/*'
);
HAS_STREAM
HAS_STREAM определяет, является ли запрос стриминговым — то есть выполняет длительное непрерывное чтение и/или запись из потоков данных. Допустимые значения:
true— классификатор срабатывает на стриминговых запросах;false— классификатор срабатывает на нестриминговых запросах.
Пример. Направить стриминговые запросы в пул pool_stream:
CREATE RESOURCE POOL CLASSIFIER cl_stream WITH (
RANK=500,
RESOURCE_POOL='pool_stream',
HAS_STREAM=true
);
Замечания
Если в DDL для создания классификатора пула ресурсов не указан RANK, то по умолчанию ему будет присвоено значение . Все значения RANK должны быть уникальными, чтобы обеспечить строго детерминированный порядок выбора пула ресурсов в случае конфликтующих условий. Такое поведение выбрано для возможности добавлять новые классификаторы пулов ресурсов между уже существующими.
Также возможно наличие классификатора, который ссылается на несуществующий пул ресурсов или к которому у пользователя нет доступа. В таком случае он пропускается.
С ограничениями на число классификаторов можно ознакомиться на странице ограничений.
Разрешения
Требуется разрешение USE на базу данных.
Пример выдачи такого разрешения:
GRANT 'USE' ON `/my_db` TO `user1@domain`;
Примеры
Ниже — сводный пример, комбинирующий несколько классификаторов и предикатов: отклонение полных сканов архивных таблиц, изоляция стриминговых запросов и выделение пула под интерактивные запросы админа из YDB UI.
Создание ресурсных пулов:
CREATE RESOURCE POOL pool_stream WITH (
TOTAL_CPU_LIMIT_PERCENT_PER_NODE=20
);
CREATE RESOURCE POOL pool_adhoc_admin WITH (
TOTAL_CPU_LIMIT_PERCENT_PER_NODE=10
);
Создание классификаторов:
-- Отклонять полные сканы архивных таблиц.
CREATE RESOURCE POOL CLASSIFIER cl_fullscan_reject WITH (
RANK=100,
ACTION='reject',
HAS_FULL_SCAN='/Root/db/orders_archive/*'
);
-- Стриминговые запросы направлять в выделенный пул.
CREATE RESOURCE POOL CLASSIFIER cl_stream WITH (
RANK=200,
RESOURCE_POOL='pool_stream',
HAS_STREAM=true
);
-- Запросы админа из YDB UI — в пул интерактивных запросов.
-- Условие AND: и MEMBER_NAME, и HAS_APP_NAME должны совпасть.
CREATE RESOURCE POOL CLASSIFIER cl_adhoc_admin WITH (
RANK=300,
RESOURCE_POOL='pool_adhoc_admin',
MEMBER_NAME='admin',
HAS_APP_NAME='ydb-ui'
);
Классификаторы обрабатываются в порядке возрастания RANK; для запроса срабатывает первый подходящий. Запрос, не удовлетворяющий ни одному классификатору, направляется в пул default.