Архитектура для загрузки больших файлов из множества конечных точек в облачное хранилище - PullRequest
0 голосов
/ 30 апреля 2019

Я работаю над настольным приложением, которое предлагает загрузку в облачное хранилище.Поставщики хранилищ имеют простой способ загрузки файлов.Вы получаете accessKeyId и secretAccessKey, и вы готовы к загрузке.Я пытаюсь найти оптимальный способ загрузки файлов.

Вариант 1. Заполните каждый экземпляр приложения ключами доступа.Таким образом, файлы могут быть загружены непосредственно в облако без посредников.К сожалению, я не могу выполнить какую-либо логику перед загрузкой в ​​облако.Например ... если у каждого пользователя есть 5 ГБ доступного хранилища, я не могу проверить это ограничение прямо у поставщика хранилища.Я не нашел ни одного поставщика, который делает это.Я мог бы отправить запрос на свой собственный сервер перед загрузкой, чтобы выполнить проверку, но поскольку ключи жестко закодированы в приложении, и я уверен, что это простой эксплойт.

Вариант 2. Отправка каждого загруженногофайл на сервер, где можно выполнить логику ограничения и переслать файл в окончательное облачное хранилище.Этот подход страдает от узкого места на сервере.Например, если 100 пользователей начинают загружать (или загружать) файл размером 1 ГБ и если скорость сервера составляет 1000 МБ / с, то каждый пользователь загружает только со скоростью 10 МБ / с = 1,25 МБ / с.

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

1 Ответ

1 голос
/ 30 апреля 2019

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

Вы можете перейти с Варианта 1. Загрузка непосредственно в провайдер хранилища., но сначала проверьте с вашим сервером.Вам необходимо уметь:

  • Идентифицировать каждого пользователя.Простой UUID может сработать, или перейти к полному пользователю / проходу.
  • Иметь базу данных, которая отслеживает использование каждым клиентом.
  • Шифровать связь между настольным приложением и вашим сервером с помощью своего личногоключ.То есть помимо HTTPS.Если вы не знаете, как работает криптография с открытым ключом , вам следует поискать ее.
  • Используйте временные ключи доступа для каждого провайдера и найдите способ справиться с этим.

Это увеличит вашу стоимость.Однако не так много, как в Варианте 2.

Ваше приложение выполнит вызов API на ваш сервер перед загрузкой, чтобы определить, является ли загрузка действительной.Любой ответ (или его отсутствие), который не является хорошим ответом, означает, что загрузка не удалась.Это также означает, что вы вводите единственную точку отказа в своей архитектуре и вам лучше убедиться, что ваш сервер всегда работает и доступен, пока у вас еще есть пользователи, в противном случае вы будете нарушать закон Уитона.Мой совет, зайдите сюда без сервера.

Вы будете использовать временные пары access_key / secret_key для загрузки файлов.Настольное приложение будет загружать файл напрямую любому поставщику, с которым вы имеете дело, но оно будет использовать пару ключ / секрет, которая меняется, скажем, каждые 12 часов.Каждый пользователь получает свою собственную пару, и вам нужно убедиться, что пользователь имеет доступ только к своим файлам.В противном случае они смогут получить доступ ко всем файлам, и вы нарушите закон Уитона.Таким образом, даже если они каким-то образом выяснят, в чем секрет, у них будет доступ не более чем на 12 часов, после чего вы будете менять ключи и отключать их.

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

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

Ваш сервер должен отслеживать файлы каждого пользователя и проверять, что то, что находится в вашей серверной базе данных, совпадает с тем, что находится в хранилище.Делай это регулярно.Ежедневно, еженедельно, каждые 2 часа, все, что работает для вас.Если вы обнаружите несоответствия, расследуйте.Может быть, они пытаются обмануть.Или, возможно, в вашем приложении есть ошибка.Это означает, что вы должны быть в состоянии определить на уровне хранилища, какой файл принадлежит какому пользователю.Это может быть так же просто, как хранить все файлы пользователя в каталоге с их UUID.Не используйте имена или электронные письма там.Никакие личные данные не должны храниться где-либо еще, кроме как в вашей базе данных.Даже там, только в случае необходимости, и это должно быть зашифровано.

Итак, это выглядит примерно так:

  1. Настольное приложение отправляет на сервер сообщение с просьбой загрузить файл.Что-то вроде «Мне нужно загрузить файл 3,7 ГБ».Сообщение шифруется перед отправкой с открытым ключом этого пользователя.
  2. Ваш сервер получает сообщение, расшифровывает его, проверяет доступное пространство, ищет подходящего провайдера в своей базе данных и получает последнюю версию access_key / secret_key дляэтот провайдер.
  3. Ваш сервер отправляет что-то вроде "ALL_GOOD, загрузить на provider_AWS_S3, используя THIS_ACCESS_KEY в паре с THIS_SECRET_KEY".Сообщение зашифровано с использованием закрытого ключа.
  4. Настольное приложение загружает файл непосредственно в S3, используя предоставленные ключи.

Загрузка и другие операции должны выполняться аналогичным образом.

Отличный вариант использования для безсерверного (Lambdaв AWS, функциях Google и т. д.), что должно снизить затраты и обеспечить повышенную избыточность и «время безотказной работы».

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

Вот, пожалуйста.Это будет $ 3000 :)

...