Skip to content

pashest/object-storage-service

Repository files navigation

object-storage-service

Схема

OSS.svg

Описание

В данной реализации API Service и Metaservice объединены в одно приложение

На сервер A (API Service) по REST присылают файл, его надо разрезать на 6 примерно равных частей и сохранить на серверах хранения Bn (n ≥ 6).

При REST-запросе на сервер A нужно достать куски с серверов Bn склеить их и отдать файл.

API Service получает информацию о серверах и по их весу определяет где сохранить каждый чанк файла. Информация о чанках и серверах хранится в БД Metaservice (PostgreSQL)

Heartbeat

API Service узнает о доступности серверов хранения через механизм Heartbeat. В ответе сервера хранения также возвращают доступное место на серверах. Это позволяет присваивать каждому серверу хранения свой вес в зависимости от оставшегося свободного места на диске. При загрузке чанка сервер хранения выбирается по самому максимальному/минимальному весу, что поволяет заполнять сервера хранения равномерно.

Загрузка файла

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

Сохранение чанков (TODO)

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

Запуск

Собираем docker-compose

docker-compose build

Поднимаем контейнеры (На текущий момент все порты и адреса захардкожены)

docker-compose up

Загрузка файла

Для загрузки и скачивания файла можно воспользоваться клиентом, однако он пока что не подходит для загрузки больших файлов (> 2Гб).

POST /upload

Загружает файл в хранилище.

  • URL: http://localhost:8080/upload

  • Метод: POST

  • Требуемые заголовки (Headers):

    • "X-Filename": "{file_name}"
    • "Content-Type": "application/octet-stream"
    • "Username": "{username}" Имя пользователя (опционально, по дефолту user)
  • Тело запроса: binary

Пример запроса через cURL

curl -X POST http://localhost:8080/upload \
  -H "X-Filename: myfile.txt" \
  -H "Content-Type: application/octet-stream" \
  -H "Username: user" \
  --data-binary "@path/to/myfile.txt"

Скачивание файла

GET /download

Скачивает файл по его имени.

  • URL: http://localhost:8080/download?file_name={file_name}
  • Метод: GET
  • Требуемые заголовки (Headers):
    • "Username": "{username}" Имя пользователя (опционально, по дефолту user)

Пример запроса через cURL

curl -X GET "http://localhost:8080/download?file_name=myfile.txt" \
  -H "Username: user" -o downloaded_myfile.txt

Табличный формат API

Метод URL Описание Заголовки
POST /upload Загружает файл "X-Filename", "Content-Type", "Username"
GET /download?file_name={file_name} Скачивает файл по имени "Username"

Хранение данных

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

Предположим, что годовая частота отказов жестких дисков составляет 1.89% (ссылка)

Обычная репликация (3 реплики) в данном случае даст только 5 девяток надежности (99.99932%), что является довольно низким показателем.

Использование RAID по типу 60, может частично решить эту проблему, однако появится проблема при дальнейшем расширении.

В данном случае лучше использовать стирающее кодирование (erasure coding), так как оно позволяет достичь большей надежности и настроить под себя сетап, для корректировки устоичивости

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published