Обновить

System Design: проектируем Dropbox, сервис для хранения и обмена файлами

Уровень сложностиСредний
Время на прочтение26 мин
Охват и читатели11K
Всего голосов 8: ↑8 и ↓0+11
Комментарии19

Комментарии 19

Без понимания экономики сервиса это всё пук в лужу.

Как увидел CDN и прочие потенциально дорогие решения сразу засомневался.

Также критично для экономики срок хранения файлов.

Не впадайте в архитектурный азарт, поставьте реальные цели и считайте каждую копейку

Здравствуйте, спасибо за комментарий!

Я не знаю, что вам ответить кроме цитаты из статьи относящейся к CDN:

Проблемы

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

Вот, думаю, что для разработчика и для архитектора требования на собеседовании совсем разные.

Реактивный дизайн (решения всплывают по ходу, требования додумываются) на собеседовании большая ошибка, я считаю. Для разработчика ок, для архитектора нет.

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

А для архитектора не хватает

1. Оценки масштаба (количества пользователей всего и активных, размер хранилища, RPS, трафик) - без них решения берутся с потолка

2. Ранжирование сценариев по частоте - что оптимизируем в первую очередь

3. Ключевые архитектурные решения до коробочек: блочная модель/чанки, иммутабельность, разделение metadata/content, модель конфликтов

4. Экономика/себестоимость - дедуплиеация, tiering, лимиты как следствие экономики

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

Нет, не должен))) 80% архитектурных ошибок отсеиваются на уровне здравого смысла (смотри выше), до технологий может и не дойти если задумка плохая

Вы правы, требования зависят от роли, на которую вы претендуете. В конце данной статьи подробно рассказываются примерные требования для Middle, Senior и Staff кандидатов (не буду цитировать, чтобы не перепечатывать в комментарии всю статью).

Конечно в разных компаниях (и даже у разных интервьюеров) они могут отличаться. Если у вас есть возможность узнать детали того как проходит System Design интервью именно в вашу целевую компанию - я всегда рекомендую кандидатам так делать. Это хорошо и для кандидата: он будет лучше готов, для него меньше неожиданностей. И для интервьюера: не нужно тратить время на объяснения, интервьюер за часовое интервью успевает собрать все сигналы по областям компетенций, которые необходимы для роли. Конечно в рамках того, что в принципе возможно собрать за час (но тут интервьюер находится в рамках процесса найма, установленных в компании).

Что касается функциональных, нефункциональных требований, структуры интервью, шаблонных и нешаблонных решений и их обоснований - это большая тема для обсуждения, ее невозможно рассказать в комментариях.

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

А для архитектора не хватает

1. Оценки масштаба (количества пользователей всего и активных, размер хранилища, RPS, трафик) - без них решения берутся с потолка

Здесь я с вами соглашусь лишь частично. Умение все это считать - требование для Middle кандидата. Неопытные кандидаты очень часто тратят на оценки слишком много времени, игнорируя большую часть результатов этих оценок. Staff+ кандидаты не тратят время на оценки, если они не имеют прямого непосредственного влияния на конкретную часть дизайна, которая сейчас рассматривается. Если прямо сейчас кандидат обсуждает нужно ли шардировать базу - самое время сделать оценки масштаба для принятия этого решения, это разумно. Но если кандидат просто посмотрел 10+ шаблонных видео на ютуб, в которых все так делают в начале интервью и поэтому он сделает так же - чтобы выглядеть "как архитектур" - это бесполезно, опытный интервьюер легко это считает.

Чел, ты пишешь как нейронка

Я и видео на ютуб записываю как нейронка. Да и вообще стоит признать, что я, в известном смысле, нейронка.

Нравится ваш подход с рассмотрением трёх альтернатив) спасибо!

судя по схеме, ходим в s3 без авторизации? На схеме стрелка идет мимо apiGW.
И перехватив гет-запрос (айдишник то в юрл), или просто посканировав все возможные варианты, мы получаем содержимое чужих файлов?

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

судя по схеме, ходим в s3 без авторизации? На схеме стрелка идет мимо apiGW. И перехватив гет-запрос (айдишник то в юрл), или просто посканировав все возможные варианты, мы получаем содержимое чужих файлов?

Лучшим решением будет реализовать и загрузку, и скачивание напрямую из/в S3 используя presigned URL, то есть с авторизацией.

Обычно на интервью достаточно сказать presigned URL и интервьюеру все понятно про суть решения и как обеспечивается авторизация. В статье 3 раздел "Погружений в детали" полностью посвящен обсуждению безопасности файлов, прочитайте, пожалуйста, еще раз.

Это распространненый паттерн, используемый во многих продуктах, подробнее про него есть в статье "Работа с большими файлами" на NowInterview, но она, к сожалению в Premium подписке.

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

А вот это хороший вопрос, и в статье он не рассмотрен явно.

Действительно, фактически у нас есть основная БД (на наших серверах) которая хранит источник истины для системы в целом, и вероятно, на клиенте есть небольшая БД этого клиента, которая все знает о локальных папках и файлах. Наша задача - поддерживать эти БД в согласованном состоянии, но при попытках делать это в режиме реального времени (постоянной синхронизации), из-за багов, разрывов сети и прочих причин может возникать несогласованность, которую сложно подфиксить теми же механизамами.

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

pre-signed url - это так себе безпоасность. Все данные передаются в урле, а значит, их легко перехватить. И по сути, единственная проблема в том, что ссылкой нужно воспользоваться в ограниченный промежуток времени. Опять же, так себе проблема.

Отдельно - а в чем проблема проверять хотя бы jwt-токен (задача со звездочкой - в токене указать, куда можно ходить)? Для этого нужно пустить трафик до s3 только через простенький api gateway, а не через все сервисы.

> Хорошим решением тут будет иметь отдельный фоновый процесс сверки (reconciliation)

Вообще не решает проблему. Вы на одной машине залили проект, на другой скачали, а оно не компилится (хорошо, если сразу не компилится, а не выстрелит потом в рантайме).

И то, что "ну, через неделю оно точно починится" (и то, если новых изменений не будет) тоже слабое оправдание.

Кажется, здесь нужно работать со снапшотами, с happens before, с версиями...

Вообще не решает проблему. Вы на одной машине залили проект, на другой скачали, а оно не компилится (хорошо, если сразу не компилится, а не выстрелит потом в рантайме).

А кто из облаков так делает? Дропбокс так не делает, мега так не делает. Это у вас какое то особое требование, кажется мне?

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

Я мыслил по аналогии, как СХД (в том числе - NAS) реплицируются. И они умеют даже несколько разделов консистентно реплицировать (например, если у вас на одном разделе - БД, а на другом - ее транзакшн лог, плохо, если они рассинхронизируются).

pre-signed url - это так себе безпоасность. Все данные передаются в урле, а значит, их легко перехватить. 

Настоящий Dropbox использует presigned URL. Я не встречал, если честно, таких обсуждений, где требования к безопасности для проектируемой на интервью системы должны быть выше чем у реального Dropbox. Если только это очень конкретная роль Security Engineer, и интервьюер хочет углубиться в эту часть.

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

Кажется, здесь нужно работать со снапшотами, с happens before, с версиями...

Да, вполне, интервьюера могут интересовать вопросы аудита и версионирования, особенно если кандидату придется иметь дело с чем-то похожим в реальной работе. Именно поэтому очень важно очертить требования на этапе их сбора в начале интервью и согласовать с интервьюером. В данном случае, мы явно проговорили, что версионирование за рамками задачи.

Смежный тут очень интересный вопрос - разрешение конфликтов. В данной статье рассмотрена простая стратегия "last write wins". Интервьюер может попросить вас углубиться в этом направлении, и в данной статье это не рассматривается.

Не хочется втюхивать вам рекламу платного ресурса, уж извините, но если вдруг интересно - тема разрешения конфликтов через операциональное преобразование или через CRDT рассмотрена в задаче Google Docs на NowInterview.

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

использую тот же url, чтобы скачать файл. А может даже, чтобы модифицировать, если ссылка дает такие права.
Если файл зашифрован - это бы сняло проблему. Но где этот ключ шифрования? В том же url в открытом виде? Тогда, он ни чем не помогает, я его же использую.

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

Данный вопрос подробно рассмотрен в статье, давайте я вам скопирую сюда

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

Здесь снова вступают в игру подписанные URL-адреса, о которых мы говорили ранее. Когда пользователь запрашивает ссылку для скачивания, мы генерируем подписанный URL-адрес, действительный только в течение короткого периода времени (например, 5 минут). Затем этот подписанный URL-адрес отправляется пользователю, который может использовать его для загрузки файла. Стоит отметить, что подписанные URL-адреса являются токенами “на предъявителя” (bearer token) - любой, у кого есть действительный, непросроченный URL-адрес, может загрузить файл. Короткий срок действия ограничивает уязвимость, но не полностью предотвращает распространение. Для более строгих сценариев безопасности можно добавить дополнительные ограничения, такие как привязка к IP-адресу, или потребовать использования подписанного URL-адреса в сочетании с аутентификационными файлами cookie.

Нет, не расмотрен. Вы хоть внимательно вчитайтесь.

Если я сопру не ссылку, предназначенную для того, чтобы делиться, а ссылку, которая действует 5 минут.

Вот же у вас написано русским по белому:

Стоит отметить, что подписанные URL-адреса являются токенами “на предъявителя” (bearer token) - любой, у кого есть действительный, непросроченный URL-адрес, может загрузить файл.

Проблема в том, что эта ссылка передается в урле. А значит, ее не получится зашифровать тем же ssl-ем.

Привязка к ip-адресу... кажется, она плохо сработает потому, что ровно тот же, кто может перехватить ваш url, будет по пути к вашему ip-адресу, а значит, сможет его подменить.

вот, кукисы с токеном хотелось бы видеть.
И то не очень понятно, как они ограничивают доступ именно к этому файлу, а не вообще ко всем файлам. Как эти права накатываются на уровне s3. Ведь тогда я могу просто с другим валидным токеном (со своим токеном) воспользоваться этой ссылкой. Тут можно придумать решение, но оно должно быть. Иначе, вы сейчас учите людей проектировать дыру в безопасности.

Если я сопру не ссылку, предназначенную для того, чтобы делиться, а ссылку, которая действует 5 минут.
Проблема в том, что эта ссылка передается в урле. А значит, ее не получится зашифровать тем же ssl-ем.

Запрос на получение presigned URL - это обычный HTTPS запрос, который под SSL. При генерации presigned URL в открытом виде есть только на сервере в момент генерации и на клиенте, как ответ на клиентский запрос. "В дороге" presigned URL зашифрован SSL.

Что касается похода с клиента уже в облачное хранилище, то
при прямом запросе в S3 presigned URL тоже защищён TLS, если ссылка c https. Query string с X-Amz-Signature не передаётся открытым текстом. Риск bearer URL не в пассивном сниффинге HTTPS-трафика, а в утечке самой ссылки из логов, истории, Referer, XSS, malware или TLS-inspection proxy.

тот же, кто может перехватить ваш url, будет по пути к вашему ip-адресу, а значит, сможет его подменить.

Подменить presigned URL подписанный HMAC с секретным ключом? Я надеюсь вы шутите

А может даже, чтобы модифицировать, если ссылка дает такие права.
...
Ведь тогда я могу просто с другим валидным токеном (со своим токеном) воспользоваться этой ссылкой.

Мне кажется вы не очень хорошо понимаете как устроен, как работает и что можно сделать с presigned URL. Вы меня извините, но это тема отдельной статьи.

Presigned URL в данном случае - стандарт индустрии, используемый в реальном Dropbox.
Впрочем, вы, конечно, в праве произвести революцию, если такое состояние дел вас не устраивает.

сорри, похоже, я затупил.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации