Tracks Flow + Open Source = Simple File Storage

в 10:40, , рубрики: open source, php, tracks flow, Блог компании Tracks Flow, метки: , , ,

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

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

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

Достоинства

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

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

Как работает

Загрузка файла происходит порциями данных (чанками) — по одному POST-запросу на один чанк. Загрузка происходит последовательно. При обработке очередного запроса сервер дописывает полученную часть в результирующий файл. Все операции инвариантны по времени к длине целевого файла.
Все файлы хранятся на файловой системе в структуре каталогов:
/<корневой_путь>/<scope>/<первые_два_символа_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. Сервис активно развивается, так что вы точно найдете что то интересное, если давно не были. Ну а для тех, кто не был еще — сегодня раздаем инвайты всем кто пришлет запрос в личку любому сотруднику компании.

Автор: Andrey_Kuprikov

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js