Перейти к содержанию

Квоты и ограничение скорости

Страница для администратора кластера и тенанта: как ограничить число бакетов, число объектов, хранимый объём, частоту запросов и скорость передачи для тенанта, пользователя или бакета, как посмотреть потребление и что означает каждое ограничение. Квота задаётся в консоли, через API управления или, если API управления не включён, средствами SQL.

Сводный перечень административных действий с запросами API управления и командами SQL приведён в приложении Г.

Что нужно знать до установки квоты

  • Квота bytes или objects, заданная впервые, начинает отклонять записи не сразу: имеющиеся объекты подсчитываются в фоне, и до конца подсчёта записи под этой квотой учитываются, но не отклоняются (см. «Учёт потребления»).
  • Строка с областью, в которой вид ограничения не действует, сохраняется, но ничего не ограничивает (см. «Виды и области»).
  • Предел value, равный 0, для видов скорости означает отсутствие ограничения, а для остальных видов запрещает любое потребление.

Виды и области

Ограничение описывают область действия (scope), цель (target), вид (kind), предел (value) и, для ограничений скорости, допустимый кратковременный всплеск (burst).

Области действия:

scope На что действует target
tenant весь тенант пустая строка
user пользователь Picodata имя пользователя
bucket бакет имя бакета

К одному запросу могут одновременно относиться ограничения нескольких областей, и запрос должен удовлетворять каждому из них.

Виды ограничений. Не каждый вид действует во всех областях:

kind Единица Области, в которых ограничение действует Что происходит при достижении предела
read_rps, write_rps запросы в секунду user, bucket сервер отвечает 503 SlowDown с заголовком Retry-After
read_bandwidth, write_bandwidth байты в секунду user, bucket передача замедляется до заданной скорости. Время передачи на этой скорости не входит в предельное время запроса ни при приёме, ни при отправке данных
buckets число бакетов tenant, user CreateBucket отвечает TooManyBuckets
bytes, objects хранимый объём и число версий объектов tenant, user, bucket отказ возвращается ответом 403 QuotaExceeded

Строка с областью, которой нет в этой таблице, сохраняется, но ничего не ограничивает. Например, ограничение частоты запросов с областью tenant на запросы не влияет.

Всплеск burst:

  • задаётся в запросах для видов *_rps и в байтах для видов *_bandwidth;
  • для остальных видов должен быть равен NULL;
  • API управления не принимает ограничение скорости без burst;
  • строка, добавленная средствами SQL со значением NULL, получает burst, равный пределу value, но не меньше 1.

Задать квоту через API управления

В установке с включённым control_api следует пользоваться API управления или консолью. В консоли ограничения всех видов, включая ограничения скорости, задаются на экране «Quotas».

Раздел /v2/quotas охватывает все виды и области:

GET /v2/quotas?tenant_id=0
PUT /v2/quotas?tenant_id=0
{"scope": "user", "target": "alice", "kind": "read_rps", "value": 200, "burst": 400}

Значение null снимает ограничение. Ответ содержит все ограничения тенанта после изменения.

Потребление сообщается для числа бакетов, хранимого объёма и числа объектов. У ограничений скорости потребления нет, потому что они ограничивают допуск запросов, а не накопленный объём.

Остальные разделы API:

Раздел Что задаёт Особенности
/v2/buckets/{бакет}/quota квоты одного бакета —
/v2/quotas/tenant_quota число бакетов и хранимый объём всего тенанта изменения передаются методом POST; изменяет только пользователь с ролью s3r_superuser
/v2/quotas/bucket_quota число бакетов и хранимый объём каждого пользователя тенанта, несмотря на название изменения передаются методом POST

Разделы tenant_quota и bucket_quota сохранены из спецификации API.

Задать квоту средствами SQL

Устройство таблицы полезно знать в двух случаях: когда API управления не включён и квоту нужно задать средствами SQL и когда нужно понять, что именно означает установленное ограничение.

Примечание

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

Квоты хранятся в строках глобальной таблицы s3r_quota. Отсутствие строки означает отсутствие соответствующего ограничения. Изменять таблицу может пользователь с ролью s3r_superuser.

Столбец Что содержит
tenant_id идентификатор тенанта
scope, target, kind, value, burst область, цель, вид, предел и всплеск (см. «Виды и области»)
set_at момент установки ограничения; при вставке средствами SQL в него записывается localtimestamp

По значению set_at учёт хранимого объёма и числа объектов отличает ограничение, снятое и заданное снова: первая запись после повторной установки пересчитывает потребление по данным, которые хранятся в этот момент. Изменение предела командой UPDATE сохраняет set_at, и учёт продолжается без пересчёта.

-- Весь тенант 0: не более 100 бакетов
INSERT INTO s3r_quota
       (tenant_id, scope, target, kind, value, burst, set_at)
VALUES (0, 'tenant', '', 'buckets', 100, NULL, localtimestamp);

-- Пользователь alice: 200 запросов на чтение в секунду,
-- с кратковременным всплеском до 400 запросов
INSERT INTO s3r_quota
       (tenant_id, scope, target, kind, value, burst, set_at)
VALUES (0, 'user', 'alice', 'read_rps', 200, 400, localtimestamp);

-- Бакет archive: не более 1 ТБ
INSERT INTO s3r_quota
       (tenant_id, scope, target, kind, value, burst, set_at)
VALUES (0, 'bucket', 'archive', 'bytes', 1000000000000, NULL, localtimestamp);

-- Новый предел для archive без пересчёта потребления
UPDATE s3r_quota SET value = 2000000000000
 WHERE tenant_id = 0 AND scope = 'bucket'
   AND target = 'archive' AND kind = 'bytes';

SELECT scope, target, kind, value, burst
  FROM s3r_quota WHERE tenant_id = 0;
-- Для бакета target содержит s3bkt_id, а не имя
SELECT scope, target, kind, used
  FROM s3r_quota_usage WHERE tenant_id = 0;

-- Удаление строки снимает только это ограничение
DELETE FROM s3r_quota
 WHERE tenant_id = 0 AND scope = 'user'
   AND target = 'alice' AND kind = 'read_rps';

Учёт потребления

Изменение квоты не перекодирует и не удаляет уже записанные данные.

Потребление хранимого объёма и числа объектов хранится в таблице s3r_quota_usage.

  • Объём учитывается по исходному размеру объектов, до сжатия.
  • В строке бакета поле target содержит не имя, а числовой идентификатор бакета s3bkt_id из таблицы s3r_bucket. Поэтому бакет, созданный заново под тем же именем, начинает учёт с нуля.
  • Число бакетов в buckets_usage совпадает с тем, с которым CreateBucket сравнивает предел: бакет, помеченный удалённым, учитывается до окончания его очистки процессом bucketgc.
  • Доли ограничений скорости данного инстанса и дерево их распределения показывает GET /-/debug/quota.

Первая установка квоты bytes или objects

При первом добавлении квоты bytes или objects имеющиеся объекты учитываются сканированием пространства имён. Сканирование выполняется в фоне и начинается с первой записи под новой квотой. Пока оно не завершено, записи под этой квотой учитываются, но не отклоняются.

Проверка при записи

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

При замене объекта предел сравнивается с потреблением, которое останется после записи. Поэтому замена объекта объектом того же или меньшего объёма выполняется и при достигнутом пределе.

Когда потребление неизвестно

Учёт объёма и числа объектов ведётся только для тенантов, пользователей и бакетов, у которых задана квота bytes или objects. Поэтому поля, которые показывают потребление, бывают равны null, то есть объём неизвестен.

Поле Что показывает Когда содержит число
bytes_used запроса /v2/capacity объём данных всех тенантов только если у каждого активного тенанта есть квота bytes с областью tenant и тенант выполнил запись после её установки: эта запись запускает подсчёт уже хранимых объектов. Квоты пользователей и бакетов весь тенант не учитывают
storage_usage настроек бакета (GET /v2/buckets/{бакет}/settings) объём, учтённый по квоте bytes с областью bucket когда у бакета есть такая квота и в бакет что-то записано после её установки. Квота тенанта поле не заполняет
objects_usage настроек бакета число объектов, учтённое по квоте objects с областью bucket так же

Известные расхождения в отчёте о потреблении, границы точности учёта и его восстановления после аварии перечислены в разделе «Квоты» главы «Ограничения».