Эта статья призвана показать метод предотвращения дублирования файлов и экономии места для хранения с помощью алгоритмов хеширования.

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

A hash function is any function that can be used to map data of arbitrary size to fixed-size values.
The values returned by a hash function are called hash values, hash codes, digests, or simply hashes.
The values are used to index a fixed-size table called a hash table

- Wikipedia

Как это работает

Я собираюсь использовать метод, который использует хранилище файлов, хранилище "ключ-значение" (hash-storage linker) и reference object для файла.

Файловое хранилище

Он отвечает за сохранение фактического файла, загруженного пользователями. Платформы хранения или службы, такие как S3, Google Storage, Block Storage, например, могут использоваться в качестве хранилища файлов.

Компоновщик хэш-хранилища

Это БД, которая содержит хеш-значение файла в качестве ключа и путь к файлу в хранилище файлов (например, S3) в качестве его значения. БД KV-store отлично подходят для хранения данных такого типа.

Он служит посредником между хранилищем файлов и ссылкой на файл.

Note: The Hash-Storage is not required for this to work. If the server uses a single folder to store all the files, it can just hash the value of the file, and save the file using the hash value.

Using the Hash-Storage makes checking the existence of the file faster since it is a KV-store. It can also act as an abstraction for separating files from file reference. Using it allows us to use multiple distributed file stores.

Если файлы существуют, должна существовать hash-storage linker запись.

Объект ссылки на файл загрузчика

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

Теперь, когда мы увидели сущности, которые играют роль в выполнении этой работы, следующий шаг - показать, как они объединяются для решения проблемы.

Загрузка потока на веб-интерфейсе

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

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

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

Поток загрузки на бэкэнд-сервере

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

Сервер ожидает метаданные файла (информацию) и значение body или hash. Используйте body, если файл не существует, и hash, если файл существует.

Если файл не существует, body необходимо отправить в теле запроса, чтобы сервер знал, что это новый файл, и создал файл в службе хранилища файлов. После создания файла сервер создает запись о hash-storage linker связывает путь к файлу в хранилище файлов с reference objects.

Последнее, что делает сервер, - это создает ссылку на файл для использования загрузчиком. Данные, содержащиеся в reference object, содержат значение хеш-ключа из hash-storage linker и дополнительную информацию о загруженном файле. Информация, такая как время загрузки, идентификатор загрузчика, имя_файла, доступ .e.t.c. Все, что нужно пользователю для работы приложения.

При использовании hash вместо body в теле запроса создайте только reference object файла.

Получите поток файлов на бэкэнде

При получении файла внутренний сервер предоставляет две конечные точки. Одна конечная точка получает объект ссылки на файл,
, а другая - фактическое содержимое файла.

Получение файла reference object - менее сложная задача на сервере.
Хэш, возвращенный с файлом reference object, может использоваться для выборки файла, но в случае, когда провайдер хранилища предоставляет что-то похожее на S3 Presigned Link, сервер может вернуть заранее подписанную ссылку для получения. Причина этого в том, чтобы снизить нагрузку на ваш сервер и перенести его на S3, который, скорее всего, лучше приспособлен для извлечения файлов из Интернета (просто так).

Получите поток файлов на веб-интерфейсе

Интерфейс использует конечную точку ссылки на файл для получения файла. Хеш-значение, извлеченное из файла reference object data, помогает определить путь для получения фактического файла на сервере или локально хранимых данных (это зависит от приложения).

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

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

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

Удаление файлов

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

При удалении reference object нам нужно знать, ссылаются ли другие reference objects на тот же hash-storage linker, что и на ближайший к удалению объект ref. Если объект no ref указывает на ссылку хэш-хранилища, мы удаляем файл с платформы файлового хранилища и удаляем запись hash-storage linker и ссылочный файл.

Если другой объект ссылки указывает на ту же запись hash-storage linker, мы удаляем только файл ссылки и оставляем hash-storage linker и хранилище файлов в покое.

Как будет выглядеть код

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

Зачем нужен почтальон? Это делает меня ленивым, и в то же время я хорошо показываю поток интерфейса.

Документация почтальона

Метод хеширования

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

In computer science, a collision or clash is a situation that occurs when two distinct
pieces of data have the same hash value, checksum, fingerprint, or cryptographic digest.

- Wikipedia

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

В этом примере я буду использовать алгоритм хеширования md5. Это объясняет мою точку зрения. Для серьезных проектов используйте то, что имеет меньше конфликтов коллизий.

Проверьте это репозиторий Github на предмет реализации.

Заключение

Честно говоря, я не знаю, как это сделать.

КОНЕЦ 🤷‍♂. Пока.