Квоты и ограничение скорости¶
Страница для администратора кластера и тенанта: как ограничить число бакетов, число объектов, хранимый объём, частоту запросов и скорость передачи для тенанта, пользователя или бакета, как посмотреть потребление и что означает каждое ограничение. Квота задаётся в консоли, через 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 |
так же |
Известные расхождения в отчёте о потреблении, границы точности учёта и его восстановления после аварии перечислены в разделе «Квоты» главы «Ограничения».