сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Облака

Объектное хранилище S3

Объектное хранилище

Посчитал, чем оно отличается по деньгам. Возьмём одинаковый объём в 47,7 гигабайта. Если это 10 тысяч крупных файлов, то сто тысяч чтений стоят 40 рублей. Если тот же объём разложен на 10 миллионов мелких файлов и читается сто миллионов раз, те же 40 рублей превращаются в 40 тысяч. Объём хранения при этом одинаковый - 95 рублей.

Стержень: это не файловая система, а хранилище объектов с оплатой за операции; отсюда и другие правила проектирования, и другие ошибки.

// Формулировки: «чем объектное хранилище отличается от диска?», «как раздавать файлы клиентам?», «зачем правила жизненного цикла?»

Почему это не диск

Тут нет каталогов - только плоский набор объектов с ключами. Слэши в ключе рисуют иллюзию папок, но переименование «папки» означает перезапись всех объектов с новыми ключами. Нет и частичной записи: объект целиком заменяется новым, дописать в середину нельзя.

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

// Отсюда главное правило проектирования: сюда кладут то, что пишется целиком и читается целиком. Картинки, документы, резервные копии, выгрузки, логи. Не кладут: файлы баз данных, то, что правится по кусочкам, и то, к чему нужен доступ за микросекунды. Попытка примонтировать объектное хранилище как обычный диск работает, но каждый вызов файловой системы превращается в сетевой запрос со всеми последствиями.

объект
цельная единица хранения с ключом; частично не правится
плоское пространство ключей
каталогов нет, слэши в имени - только видимость

Доступ: не раздавайте всё публично

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

Правильный способ - ссылка с подписью и сроком: приложение генерирует ссылку, которая работает, скажем, пятнадцать минут и только на этот объект. Хранилище при этом закрыто, а раздача идёт напрямую от него, мимо вашего приложения - значит, вы не тратите на это ни трафик приложения, ни его потоки.

// Загрузку от пользователя делают тем же приёмом наоборот: приложение выдаёт подписанную ссылку на запись, и браузер грузит файл прямо в хранилище. Иначе весь пользовательский поток идёт через ваши серверы. И отдельно про доступ сервисов: им выдают не общий ключ, а роль с правами на конкретный набор объектов, потому что общий ключ живёт вечно и утекает вместе с любым логом.

подписанная ссылка
временный доступ к одному объекту без открытия всего хранилища
прямая загрузка
браузер грузит файл в хранилище, минуя ваши серверы

Классы хранения и жизненный цикл

У объекта есть класс хранения, и цена между классами отличается в разы. Посчитал на пяти терабайтах логов: держать всё в горячем классе - 10 тысяч рублей в месяц; всё в холодном - 3,5 тысячи; всё в архивном - тысяча.

Но держать всё в архиве нельзя: у холодных классов есть минимальный срок хранения и плата за извлечение, а у архивного - ещё и время подготовки: минуты в лучшем случае, часы в худшем. Поэтому применяют правило жизненного цикла: тридцать дней горячо, потом девяносто холодно, дальше архив, а через год удалить. По моему расчёту это даёт 2650 рублей вместо 10 тысяч - экономия 74% на одной настройке.

// Две вещи, которые обязательно включают рядом. Хранение прошлых версий объекта: без него перезапись необратима, а удаление тем более. И блокировка удаления для резервных копий - тогда даже тот, кто получил доступ, не сможет стереть архив раньше срока. Правило жизненного цикла при этом надо писать аккуратно: оно применяется само, и ошибка в фильтре молча удалит не то.

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

Как отвечать: «Как правильно раздавать пользовательские файлы через объектное хранилище?»

Хранилище держу закрытым, а клиенту выдаю подписанную ссылку с коротким сроком - скажем, пятнадцать минут и только на конкретный объект. Тогда файл едет напрямую из хранилища, минуя мои серверы: я не трачу ни трафик приложения, ни его потоки. Загрузку делаю зеркально: приложение выдаёт подписанную ссылку на запись, и браузер грузит файл прямо в хранилище. Публичное хранилище не использую вообще - именно так регулярно утекают чужие документы и резервные копии. Сервисам выдаю не общий ключ, а роль с правами на нужный набор объектов, потому что общий ключ живёт вечно и утекает вместе с логами. И сразу настраиваю жизненный цикл: я считал на пяти терабайтах логов, что перевод в холодный и архивный классы по возрасту даёт экономию около 74% против хранения всего в горячем.

Ответ закрывает и безопасность, и нагрузку на приложение, и деньги. Подписанные ссылки в обе стороны - признак того, что человек это делал.

На чём валятся

  • Открывают хранилище публично ради простоты раздачи.
  • Гонят все загрузки и скачивания через своё приложение и упираются в его потоки.
  • Кладут в объектное хранилище то, что правится по кусочкам.
  • Считают только объём и не считают операции: миллионы мелких файлов стоят в разы дороже.
  • Не включают хранение прошлых версий: перезапись объекта необратима.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 7, остальные разбираются в тренажёре.

  1. #dvo_object_storage1 / 5
    Приложение отдаёт пользовательские файлы, проксируя их через себя из бакета. Как сделать лучше?
    A)Кэшировать файлы на диске приложения после первой отдачи
    B)Отдавать подписанную ссылку с коротким сроком
    C)Открыть бакет на публичное чтение и раздавать прямые ссылки
    D)Поднять реплику бакета рядом с приложением и читать из неё
    показать ответ и разбор
    +B)Отдавать подписанную ссылку с коротким сроком

    // разбор: Проксирование через приложение занимает его потоки и полосу ради работы, которую хранилище делает лучше. Подписанная ссылка с коротким сроком даёт клиенту прямой доступ к конкретному объекту, оставляя проверку прав на стороне приложения. Сверху обычно ставят CDN: тогда популярные файлы отдаются с ближайшей точки, а расходы на исходящий трафик из хранилища падают.

  2. #dvo_object_storage2 / 5
    Бакет с логами растёт и стоит всё дороже. Что настраивают в первую очередь?
    A)Сжатие на стороне хранилища для всех объектов
    B)Ограничение на размер бакета, чтобы запись остановилась
    C)Перенос старых логов в другой бакет ночным скриптом
    D)Политика жизненного цикла: класс и удаление
    показать ответ и разбор
    +D)Политика жизненного цикла: класс и удаление

    // разбор: Политика жизненного цикла — штатный механизм: объекты старше месяца уезжают в более дешёвый класс хранения, старше года удаляются, недоделанные многочастевые загрузки чистятся автоматически. Это дешевле и надёжнее скриптов. Помнить надо про две вещи: у холодных классов есть минимальный срок хранения и плата за извлечение, а при включённом версионировании удаление создаёт маркер и старые версии тоже надо чистить правилом.

  3. #dvo_object_storage3 / 5
    Объектное хранилище декларирует «11 девяток» надёжности. Значит ли это, что бэкап данных в нём не нужен?
    A)Да: при такой надёжности данные защищены от всего
    B)Да, если включить репликацию в другой регион
    C)Нет, потому что объектное хранилище часто недоступно
    D)Нет: девятки про железо, не про ошибочное удаление
    показать ответ и разбор
    +D)Нет: девятки про железо, не про ошибочное удаление

    // разбор: «11 девяток» durability означают крайне низкую вероятность потери объекта из-за отказа железа (данные реплицируются внутри хранилища). Но это не защита от логических бед: ошибочное удаление, перезапись, баг в коде, скомпрометированный ключ сотрут/испортят объект, и репликация растиражирует это. Защищаются версионированием (хранить прежние версии), MFA-delete, политиками и отдельными неизменяемыми копиями. Durability и «бэкап от своих ошибок» — разные вещи.

  4. #dvo_object_storage4 / 5
    В бакет с приватными данными пользователей случайно открыли публичный доступ. Как правильно не допускать такого?
    A)Полагаться на сложное имя бакета, его не угадают
    B)Оставить публичный доступ, но зашифровать объекты
    C)Block Public Access + подписанные ссылки
    D)Раздать всем один общий ключ доступа к бакету
    показать ответ и разбор
    +C)Block Public Access + подписанные ссылки

    // разбор: Публично открытый бакет — классическая утечка. Правильно: включить Block Public Access (запрет публичного доступа на уровне аккаунта и бакета, чтобы случайная политика его не открыла), а нужные файлы отдавать точечно — подписанными ссылками с коротким сроком или через CDN с контролем доступа. Шифрование at-rest от публичного скачивания не защищает (сервис отдаёт расшифрованное), а секретность имени и общий ключ — не контроль доступа.

  5. #dvo_object_storage5 / 5
    Нужно заливать в объектное хранилище очень большие файлы и держать высокую пропускную. Что для этого используют?
    A)Одним PUT целиком, просто с большим таймаутом
    B)Multipart-загрузку: файл частями параллельно, с докачкой упавших
    C)Сжать файл на клиенте, чтобы влез в один запрос
    D)Разбить файл на отдельные объекты с разными именами
    показать ответ и разбор
    +B)Multipart-загрузку: файл частями параллельно, с докачкой упавших

    // разбор: Большие объекты заливают multipart upload: файл режут на части и грузят их параллельно, каждую можно повторить при обрыве, а в конце хранилище собирает объект целиком. Это даёт и скорость (параллелизм насыщает канал), и устойчивость (упавшую часть докачивают, а не весь файл заново). Для высокой частоты запросов дополнительно продумывают распределение ключей/префиксов, чтобы нагрузка не била в один «горячий» префикс.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.