Структура каталогов для файлового хоста - PullRequest
3 голосов
/ 05 марта 2009

У меня есть простой файловый хост, который присваивает файлам уникальный идентификатор и просто сохраняет их в каталоге. Мне сказали, что это вызовет проблемы в будущем, и мне интересно, на что мне стоит обратить внимание, чтобы убедиться, что оно будет работать гладко в будущем и за его пределами.

Кроме того, существует ли проблема с производительностью при принудительной загрузке путем отправки информации заголовка и readfile ()? Было бы лучше сохранить имена файлов и разрешить пользователям использовать прямую загрузку, а не использовать сценарий?

Спасибо

Ответы [ 5 ]

6 голосов
/ 05 марта 2009

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

Чтобы обойти это, не храните ваши файлы непосредственно в одном каталоге, но попробуйте распространить их в подкаталогах ( buckets ).

Чтобы добиться этого, посмотрите на идентификатор (скажем, 19873) файла, который вы собираетесь сохранить, и сохраните его под <uploads>/73/98/19873_<filename.ext>, где 73 - ID % 100, 98 - (ID / 100) % 100 и т. Д.

Вышеуказанное гарантирует, что у вас будет не более 100 подкаталогов под <uploads> и не более 100 дополнительных подкаталогов под <uploads>/*. Это значительно сократит количество файлов в каталоге на листьях.

Два уровня подкаталогов достаточно типичны и представляют собой хороший баланс между тем, что не нужно тратить слишком много времени на преобразование имен каталогов или файлов в inode по ширине (что происходит, когда у вас слишком много имен файлов для просмотра в одном каталоге - хотя современные файловые системы, такие как ext3, будут очень эффективными здесь) и глубина (что происходит, когда вам нужно углубиться в 20 подкаталогов в поисках вашего файла). Вы также можете выбрать большее или меньшее значение (10, 1000) вместо 100. Два уровня по модулю 100 идеально подходят для файлов размером от 100 тыс. До 5 млн.

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

3 голосов
/ 05 марта 2009

Кроме того, существует ли проблема с производительностью при принудительной загрузке путем отправки информации заголовка и readfile ()?

Да, если вы делаете это наивно. Хороший скрипт загрузки файлов должен:

  • потоковых файлов, чтобы избежать заполнения памяти
  • поддержка ETag и Last-Modified заголовков запросов / ответов для обеспечения работы кэшей
  • предлагает разумные настройки Expires / Cache-Control

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

Было бы лучше сохранить имена файлов и разрешить пользователям использовать прямую загрузку, а не использовать сценарий?

Да, это будет работать лучше, но обеспечение безопасности - сложная задача. См. здесь для некоторого обсуждения.

Компромиссом является использование перезаписи, чтобы URL выглядел примерно так:

hxxp://www.example.com/files/1234/Lovely_long_filename_that_can_contain_any_Unicode_character.zip

Но он перенаправляется изнутри на:

hxxp://www.example.com/realfiles/1234.dat

и обслуживается (быстро) веб-сервером.

3 голосов
/ 05 марта 2009

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

Во-первых, да, многие файлы в одном месте могут вызвать проблемы, когда количество файлов превышает систему ARG_MAX. Другими словами, rm -rf * завершит работу, жалуясь на слишком много аргументов. Вы можете подумать о наличии директорий A-Z / a-z и парковке файлов соответствующим образом, основываясь на значении самого левого байта в его уникальном имени.

Кроме того, старайтесь избегать процессов, которые будут открывать все эти файлы за короткий промежуток времени ... Кроны вроде «updatedb» вызовут проблемы, когда вы действительно начнете заполняться. Аналогичным образом, постарайтесь не допустить, чтобы эти каталоги были недоступны командам вроде 'find'.

Это приводит к другой потенциальной проблеме, буферам. Как часто эти файлы доступны? Если бы в данном каталоге было 300 файлов, будет ли доступ ко всем из них хотя бы раз в 30 минут? Если это так, вы, вероятно, захотите включить параметр / proc / sys / vfs_cache_pressure, чтобы Linux освободил больше памяти и сделал ее доступной для PHP / Apache / Etc.

Наконец, что касается readfile ... Я бы предложил использовать прямую ссылку для скачивания. Это позволяет избежать необходимости поддерживать PHP во время загрузки.

1 голос
/ 05 марта 2009

Если у вас есть тысячи файлов, вы должны распространить их по многим подкаталогам.

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

0 голосов
/ 05 марта 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...