Кейс: хранение документов и файлов (MinIO)
↑ 8.4 Backend System Design · ← Предыдущая
Зачем это на собесе
Задача на хранение больших бинарных данных, права доступа и доставку.
Объяснение
Требования: загрузка и скачивание файлов (от КБ до ГБ), версии документов, права доступа, предпросмотр, антивирус, срок хранения, аудит, высокая надёжность данных.
flowchart LR U[Клиент] -->|1. запрос на загрузку| API[Files API] API -->|метаданные + pre-signed PUT| U U -->|2. загрузка напрямую| S3[(MinIO / S3)] S3 -.событие ObjectCreated.-> QОчередь Q --> W[Воркер: антивирус, превью, метаданные] W --> DB[(БД метаданных)] U -->|3. скачивание| CDN[CDN/прокси] --> S3
Решения:
| Вопрос | Решение |
|---|---|
| Хранение | объектное хранилище (S3/MinIO); в БД только метаданные (id, ключ, размер, тип, владелец, версия, хэш) |
| Загрузка | pre-signed URL / multipart для больших файлов, докачка; файл не проходит через приложение |
| Скачивание | pre-signed GET с коротким сроком либо прокси с проверкой прав; CDN для публичных |
| Права | проверка в API; ключи объектов не угадываются (GUID) |
| Версионирование | versioning bucket или версии в метаданных |
| Надёжность | erasure coding/репликация, несколько узлов/зон, бэкапы |
| Целостность | хэш (SHA-256), проверка после загрузки |
| Безопасность | шифрование в покое и в транзите, антивирус, ограничение типов/размеров, изоляция |
| Дедупликация | по хэшу содержимого (content-addressable) |
| Жизненный цикл | lifecycle: перенос в холодное хранилище, удаление |
| Метаданные для поиска | отдельный индекс (Elasticsearch) |
| Аудит | журнал доступа к документам |
Готовые предпросмотры: генерируются воркером по событию, кэшируются.
Нюансы и подводные камни
- Загрузка через приложение упирается в память и пропускную способность.
- Файл появился в хранилище, но метаданные не записались (и наоборот): согласуйте через события/сверку и очистку «сирот».
- Публичные ссылки без срока и проверки утекают.
- Имена файлов клиента — только как метаданные.
- Ограничения размера и время жизни pre-signed ссылок.
Практика
- Реализуйте загрузку через pre-signed multipart URL и обработку события
ObjectCreated. - Добавьте проверку хэша и антивирус в воркер.
- Настройте lifecycle для временных файлов и версионирование.
Вопросы с ответами
Как загружать большие файлы?
Multipart-загрузка напрямую в хранилище по pre-signed URL, минуя приложение, с докачкой по частям.
Где хранить метаданные?
В реляционной БД с ключом объекта; сами файлы — в объектном хранилище.