Tracks Flow corporate blog
Open source
August 2012 30

Tracks Flow + Open Source = Simple File Storage

Рады сообщить, что проект Tracks Flow начинает поддержку Open Source сообщества. Сегодня мы выкладываем в открытый доступ простенькую разработку — сервер хранения файлов на PHP с клиентской библиотекой на C#.

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

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

Достоинства


  • компактный код — легко проверить и поправить под себя
  • хорошая масштабируемость по количеству хранимого контента
  • отсутствие БД
  • возможность работы с файлами произвольного размера*

* Единственная функция, которая может некорректно работать на больших файлах — проверка md5 суммы файла. Функция может вызывать TimeOutException.

Как работает


Загрузка файла происходит порциями данных (чанками) — по одному POST-запросу на один чанк. Загрузка происходит последовательно. При обработке очередного запроса сервер дописывает полученную часть в результирующий файл. Все операции инвариантны по времени к длине целевого файла.
Все файлы хранятся на файловой системе в структуре каталогов:
/<корневой_путь>//<первые_два_символа_id>/<вторые_два_символа_id>/<пятый-последний_символ_id>/<filename.ext>
При загрузке файла в целевой директории создаются временные файлы, которые затем удаляются.
Скачивание файлов происходит путем передачи в Nginx заголовка X-ACCEL_REDIRECT с путем к файлу. Отгрузкой занимается сам Nginx.

Как настроить и запустить


  1. Ставим Nginx + php-fpm.
  2. В nginx создаем конфиг для хоста системы хранения примерно следующего содержания:
    server { listen <your_LAN_ip>; server_name <you_file_storage_hostname>; location /<location_name> { internal; root <storage_root_path_should_be_the_same_in_lib.php>; } location ~ \.php { root /<path_to_php_code>; fastcgi_pass 127.0.0.1:9000; #fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /<path_to_php_code>/$fastcgi_script_name; include fastcgi_params; } }
  3. Копируем файлы сервера в директорию <path_to_php_code>
  4. Проверяем lib.php – функция getfsroot() должна возвращать путь, указанный в конфиге в <storage_root_path_should_be_the_same_in_lib.php>; функция getlocroot() должна содержать то же, что указано в конфиге в <location_name>.
  5. Ставим права на <storage_root_path_should_be_the_same_in_lib.php> те же, что и у Nginx / php-fpm, даем право записи.
  6. Если мы хотим использовать чанки больше 512КБайт, то надо прописать в php-fpm, nginx и php.ini соответствующие значения для ограничений на аплоад.

Как масштабироать


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

Use Case


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

Ссылки


Git-репозиторий решения: https://github.com/tracksflow/FileStorage

Ну и, конечно, приглашаем вас на TracksFlow.com. Сервис активно развивается, так что вы точно найдете что то интересное, если давно не были. Ну а для тех, кто не был еще - сегодня раздаем инвайты всем кто пришлет запрос в личку любому сотруднику компании (не забывайте в сообщении указать адрес эл. почты).

+13
7.2k 44
Comments 6
Top of the day