Оптимальный способ обслуживания 70000 статических файлов (jpg)?

Мне нужно обслужить около 70000 статических файлов (jpg), используя nginx. Должен ли я сбросить их все в один каталог, или есть лучший (эффективный) способ? Поскольку имена файлов являются числовыми, я подумал о том, чтобы иметь структуру каталогов, например:

ххх / хххх / ххх

ОС CentOS 5.1

12 ответов

Решение

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

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

Но не верь мне, я понятия не имею, что я делаю! Мера производительности, когда это важно!

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

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

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

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

Как уже говорили другие, очень вероятно, что хеширование каталогов будет наиболее оптимальным.

Хотя я бы посоветовал вам сделать так, чтобы ваши URI не зависели от схемы каталогов, которую вы используете, используя модуль перезаписи nginx, например map example.com/123456.jpg в /path/12/34/123456.jpg.

Затем, если ваша структура каталогов нуждается в изменении по соображениям производительности, вы можете изменить это без изменения опубликованных URI.

Вы можете поместить кеш squid на ваш сервер nginx. Squid может хранить популярные изображения в памяти или использовать собственный формат файла для быстрого поиска.

Для Squid по умолчанию используется 16 каталогов первого уровня и 256 уровней второго. Это разумные значения по умолчанию для моих файловых систем.

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

Выполнение некоторого базового хеширования каталогов, как правило, хорошая идея. Даже если ваша файловая система хорошо работает с файлами 70 КБ; скажем, миллионы файлов в каталоге станут неуправляемыми. Кроме того - как ваша программа резервного копирования, как много файлов в одном каталоге и т. Д. И т. Д.

Тем не менее, чтобы получить репликацию (избыточность) и более легкую масштабируемость, рассмотрите возможность хранения файлов в MogileFS, а не только в файловой системе. Если файлы небольшого размера и некоторые файлы гораздо более популярны, чем другие, рассмотрите возможность использования Varnish (varnish-cache.org) для их обслуживания очень быстро.

Еще одна идея: использовать CDN - они на удивление дешевы. Мы используем тот, который стоит в основном столько же, сколько мы платим за "обычную пропускную способность"; даже при низкой нагрузке (10-20 Мбит / с).

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

Однако вы также можете посмотреть на параметр open_file_cache внутри nginx. См. http://wiki.nginx.org/NginxHttpCoreModule

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

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

Стоит ли вам копировать эти файлы в корзину Amazon S3 и обслуживать их оттуда?

Пусть они беспокоятся об оптимизации.

Я не знаю aboutext4, но стоковая ext2 не может обработать столько файлов в одном каталоге, reiserfs (reiser3) был разработан для такой обработки (ls все равно будет уродливым).

Организация файлов больше зависит от производительности и стабильности файловой системы, чем от производительности доставки. Я бы избегал ext2/ext3 и использовал xfs или reiser.

Вы действительно хотите изучить кеширование. Будь то встроенное кэширование на веб-сервере или стороннее кэширование типа лака.

Как упомянул kquinn, сравнительный анализ будет реальным показателем прироста / снижения производительности.

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

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

images/
  021398012.jpg
  379284790.jpg
  ...
  000/
    000/
      000000000.jpg
      000000001.jpg
      ...
    001/
      ...
    002/
      ...

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

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

PS Я в некотором роде увлекся теорией, но kquinn прав, вам действительно нужно провести несколько экспериментов, чтобы увидеть, что работает лучше для вас, и очень возможно, что разница будет незначительной.

Другие вопросы по тегам