Тенанты¶
Страница объясняет, как один кластер S3R обслуживает несколько независимых потребителей — тенантов: как разделены их данные, как запрос относится к тенанту и что настраивается для тенанта и его бакетов — дедупликация и сжатие. Она нужна администратору, который заводит тенантов и выдаёт им адреса и ключи доступа.
Коротко
- Тенант — отдельное пространство имён со своими таблицами. Оборудование у тенантов общее.
- Тенанта запроса определяют заголовок
Hostи ключ доступа. Если они указывают на разных тенантов, запрос отклоняется с ответом403. - Дедупликация и сжатие по умолчанию выключены и действуют только на записи, выполненные после включения.
Как разделены данные тенантов¶
Один кластер обслуживает несколько тенантов, и каждый тенант представляет собой отдельное пространство имён.
| Что хранится | Где | Как отделено |
|---|---|---|
| Объекты, директории, составные загрузки и служебные очереди тенанта | Собственные таблицы тенанта: s3r_t<N>_object, s3r_t<N>_dir, s3r_t<N>_mpu и другие, где N — номер тенанта |
Запрос не может обратиться к объектам другого тенанта, потому что не может назвать его таблицу |
| Бакеты | Глобальная таблица s3r_bucket |
Идентификатор тенанта входит в ключ строки бакета |
| Ключи доступа | Глобальная таблица s3r_credential |
Идентификатор тенанта указан в строке ключа доступа |
Тенант с номером 0 и именем default служит тенантом по умолчанию. Если в
кластере не создано других тенантов, кластер целиком принадлежит ему и всё
описанное в остальных разделах руководства относится к нему.
Определение тенанта запроса¶
Запрос может указывать тенанта двумя способами, и решение принимается по обоим:
- заголовок
Hostс FQDN тенанта изs3r_tenant.fqdnуказывает тенанта ещё до разбора запроса; - ключ доступа указывает тенанта через столбец
s3r_credential.tenant_id.
Если запрос указывает тенанта обоими способами, они должны совпадать:
- тенанты совпадают — запрос относится к этому тенанту;
- тенанты разные — запрос отклоняется с ответом
403; - запрос без обоих признаков относится к тенанту 0.
Ключ одного тенанта, пришедший на FQDN другого, отклоняется, а не разрешается в пользу одного из них: молчаливый выбор открыл бы путь к чтению данных другого тенанта.
Адресация тенанта¶
Тенант с заданным domain отвечает по своему FQDN в обеих формах адресации:
Формат пути: FQDN тенанта, бакет и ключ указаны в пути
https://acme.s3.example.net/documents/report.pdf
Виртуально-хостовая адресация: бакет указан меткой перед FQDN тенанта
https://documents.acme.s3.example.net/report.pdf
Точка входа по умолчанию — обращение по IP-адресу или имени узла без FQDN тенанта. Такой запрос обрабатывается как путь, а тенант определяется по ключу доступа; по умолчанию это тенант 0.
Хост, похожий на схему адресов тенантов, но не принадлежащий ни одному из них, отклоняется, а не обслуживается тенантом по умолчанию. Иначе запросы к несуществующему тенанту попадали бы к данным тенанта по умолчанию.
Смежные темы описаны на других страницах:
- собственный сертификат тенанта и обязательный клиентский сертификат — в разделе Сертификат тенанта и выбор по SNI;
- роли
s3r_superuserиs3r_tenant_admin_<id>— в разделе Ролевая модель тенантов.
Дедупликация¶
При дедупликации объекты с одинаковым содержимым хранят одну общую копию. Совпадения находит индекс дедупликации по сумме SHA-256 содержимого.
По умолчанию дедупликация выключена. Её включают для тенанта или для бакета:
-
SQL-запросом:
UPDATE s3r_bucket SET dedup = true WHERE tenant_id = 0 AND name = 'archive'; UPDATE s3r_tenant SET dedup = true WHERE tenant_id = 0; -
для бакета — в консоли, переключателем рядом с переключателем сжатия;
- для бакета — в API управления:
PUT /v2/buckets/{bucket}/deduplicationс телом{"dedup": true}.
Пока дедупликация выключена, запись не оставляет никаких следов: ни записи в очереди, ни отпечатка содержимого в индексе дедупликации.
Включение действует только на новые записи
Дедуплицируются записи, начатые после включения. Ранее записанные объекты в индекс не попадают.
Причина в сумме SHA-256: при выключенной дедупликации запись вычисляет её, только если клиент её запросил (см. Контрольные суммы S3). Отсюда следует:
- запись, которая началась до включения и не запрашивала SHA-256, не дедуплицируется, даже если завершилась после него;
- то же относится к частям составной загрузки, переданным до включения;
- копирование объекта в тот же ключ, например для замены метаданных, не переписывает содержимое и не добавляет объект в индекс.
Выключение не разделяет уже объединённое содержимое: записанное при включённом переключателе остаётся общим, но новые объекты к нему не добавляются.
Сжатие¶
По умолчанию сжатие выключено. Объект сжимается, если включён хотя бы один из трёх переключателей:
| Переключатель | Как задаётся |
|---|---|
| Бакета | в консоли на странице настроек бакета; запросом API управления PUT /v2/buckets/{bucket}/compression с телом {"compress": true}; средствами SQL |
| Тенанта | только средствами SQL |
| Яруса | полем compress: true в записи яруса параметра s3r_storage.tiers (см. Классы хранения S3 и ярусы) |
Переключатель яруса учитывается только при записи объекта операцией
PutObject: части составной загрузки и копии объектов он не сжимает.
UPDATE s3r_bucket SET compress = true WHERE tenant_id = 0 AND name = 'archive';
UPDATE s3r_tenant SET compress = true, compress_level = 6 WHERE tenant_id = 0;
Включение действует только на новые записи
Переключатели действуют на записи, выполненные после их включения. Уже записанные объекты не перезаписываются.
Алгоритм и уровень¶
Применяется алгоритм zstd. Уровень сжатия задаётся для тенанта столбцом
s3r_tenant.compress_level и действует для любого задействованного
переключателя. Значение NULL означает уровень 3. Значение вне допустимого
для zstd диапазона заменяется ближайшей границей диапазона.
Что и как сжимается¶
- Содержимое объекта сжимается участками по 1 МиБ до разбиения на полосы. Поэтому сжимаются объекты как с избыточным кодированием, так и с репликацией.
- Участок, который после сжатия занимает больше 0,9 исходного размера, хранится без сжатия.
- Чтение диапазона распаковывает только затронутые участки, но каждый из них целиком: запрос даже одного байта распаковывает до 1 МиБ.
- Объекты со способом хранения
inlineне сжимаются.
Перенос между ярусами и дедупликация¶
Перенос объекта в другой ярус правилом жизненного цикла сохраняет его форму: несжатый объект не сжимается и в ярусе с включённым сжатием. Если перенос выполняется на том же инстансе, сжатый объект сжимается заново с уровнем 3, а не с уровнем тенанта.
Общее содержимое при дедупликации хранится в той форме, в которой была записана его первая копия.
Нагрузка и наблюдение¶
Сжатие и распаковку выполняют рабочие потоки плагина (среды выполнения Tokio), которые обслуживают запрос (см. Процессорные ядра).
- Степень сжатия показывает метрика
s3r_compression_bytes_totalкак отношение значения с меткойdirection="stored"к значению с меткойdirection="logical". - Ответ
HeadObjectна запрос всего объекта содержит заголовкиx-s3r-codecс алгоритмом иx-s3r-stored-bytesс хранимым объёмом. - Квоты учитывают объём объекта до сжатия.
Ролевая модель тенантов¶
Миграции создают три роли. Субъект доступа S3 соответствует пользователю SQL Picodata, поэтому ролевая модель использует роли Picodata, а не отдельную таблицу плагина.
| Роль | Что даёт |
|---|---|
s3r_superuser |
полные полномочия над плагином в кластере и доступ SQL ко всем таблицам плагина |
s3r_observer |
только чтение состояния кластера |
s3r_tenant_admin_<идентификатор> |
управление пользователями, ключами и бакетами одного тенанта |
Роль выдаётся обычным оператором SQL. Оба имени берутся в кавычки, иначе они приводятся к нижнему регистру:
GRANT "s3r_superuser" TO "ivanov";
Роли не наследуют друг друга: если пользователю нужны полномочия двух видов, ему выдают две роли.
s3r_superuser¶
Полные полномочия над плагином в кластере:
- ярусы и уровни избыточности;
- режим обслуживания;
- тенанты и их сертификаты;
- доступ SQL ко всем таблицам плагина.
Это единственная роль с правом чтения s3r_tenant, поскольку она же записывает в таблицу
сертификаты. Её обладатель создаёт тенантов и их сертификаты, а также получает список тенантов и
сведения об их ёмкости с помощью SQL.
s3r_observer¶
Только чтение: ёмкость, состояние кластера и дисков, группы размещения, восстановление, проверка целостности. Роль предназначена тому, кто наблюдает за кластером и ничего в нём не меняет; без неё такому человеку пришлось бы выдать полномочия администратора.
Секреты наблюдателю недоступны: s3r_credential хранит секретные ключи, s3r_tenant хранит
закрытые ключи TLS, и обе таблицы выданы только s3r_superuser.
s3r_tenant_admin_<идентификатор>¶
Управление пользователями, ключами и бакетами одного тенанта, идентификатор которого указан в имени роли. Такая роль создаётся для каждого тенанта.
| Свойство | Объяснение |
|---|---|
| Отдельная роль на тенанта | полномочие нельзя выразить табличным разрешением: s3r_credential является глобальной таблицей, а разрешение SQL нельзя сузить до строк одного тенанта. Область действия задаёт выдача роли |
| В имени идентификатор, а не имя тенанта | идентификатор не переиспользуется после удаления тенанта, поэтому выданная роль никогда не станет означать другого тенанта, и переименование тенанта её не ломает |
| Чужой тенант отвечает «не найдено», а не «запрещено» | ответ «запрещено» подтвердил бы, что такой тенант существует |
| Пароль для входа по SQL | администратор тенанта его не задаёт: это может только s3r_superuser, см. Пароль для входа по SQL |
CREATE USER |
полномочие уровня кластера, которое нельзя сузить до тенанта. Поэтому администратор тенанта не получает его напрямую: пользователя Picodata создаёт плагин |
Операции предоставляет API управления. Он принимает токен доступа OIDC и тенанта в самом запросе, поэтому именно выданная роль определяет, к какому тенанту обращение допустимо.
Запросы администратора тенанта¶
| Запрос | Действие |
|---|---|
GET /v2/users?tenant_id=<id> |
перечислить пользователей тенанта и их ключи (без секретов) |
POST /v2/users |
зарегистрировать пользователя |
PUT /v2/users?tenant_id=<id> |
заблокировать или разблокировать пользователей (state) |
DELETE /v2/users?tenant_id=<id> |
удалить пользователей |
POST /v2/credentials?tenant_id=<id> |
выдать ключ доступа |
PUT /v2/credentials/<ключ>?tenant_id=<id> |
заменить секрет, сохранив ключ |
DELETE /v2/credentials/<ключ>?tenant_id=<id> |
удалить ключ |
PUT /v2/buckets с именем бакета и именем нового владельца |
передать бакет другому владельцу; в консоли это действие «передать» |
Правила:
- Секретный ключ. Ответ на создание или замену ключа содержит секретный ключ доступа только один раз. Больше его не возвращает ни один запрос.
- Блокировка действует на пользователя, а не на отдельный ключ: все ключи пользователя переходят в состояние «отключён» вместе. Операция обратима: ключи остаются, и разблокировка возвращает прежнее состояние.
- Передача бакета. Новый владелец должен быть субъектом доступа того же тенанта. Прежний владелец не сохраняет никаких прав на бакет. В ответе назван тот, кто потерял владение; больше нигде прежний владелец не записан.
См. также¶
- Репликация между площадками — почему набор площадок нельзя задать отдельному тенанту.
- Квоты и ограничение скорости.