У меня есть веб-сайт, на котором будут храниться изображения профиля пользователя. Каждое изображение хранится в каталоге (Linux), специфичном для пользователя. В настоящее время у меня 30+ клиентов, что означает, что у меня будет более 30 папок. Но моя текущая версия Linux (ext2 / ext3) не поддерживает создание более 32000 каталогов. Как мне пройти это? Даже у ребят на YouTube такая же проблема, с видео-миниатюрами. Но они решили это, перейдя на ReiserFS. Разве у нас не может быть лучшего решения?
Обновление: когда их спрашивали в IRC, люди спрашивали об обновлении его до ext4, который имеет ограничение в 64 КБ, и, конечно, вы даже можете пройти через это . Или взлом ядра для изменения лимита.
Обновление: как насчет разделения базы пользователей на папки на основе диапазона идентификаторов пользователей. Значение 1-1000 в одной папке, 1000-2000 в другой, вот так. Это кажется простым. Что скажешь, ребята?
Честно говоря, нет другого пути?
источник
Ответы:
Это ограничение для каждого каталога, а не для всей файловой системы, так что вы можете обойти его путем дальнейшего разделения вещей. Например, вместо того, чтобы все пользовательские подкаталоги в одном и том же каталоге разделяли их на первые два символа имени, вы получаете что-то вроде:
Еще лучше было бы создать некоторую форму хеширования имен и использовать ее для разделения. Таким образом, вы получите лучшее распределение по каталогам, а не с начальным примером букв, когда «da» будет очень полным, а «zz» - полностью пустым. Например, если вы берете CRC или MD5 имя и используете первые 8 бит, вы получите что-то вроде этого:
Это может быть расширено до необходимых глубин, например, так, если используется имя пользователя, а не хеш-значение:
Этот метод используется во многих местах, таких как кеш squid, для копирования примера Людвига и локальных кешей веб-браузеров.
Важно отметить, что с ext2 / 3 вы начнете сталкиваться с проблемами производительности, прежде чем вы все равно приблизитесь к пределу 32000, так как каталоги ищутся линейно. Переход на другую файловую систему (например, ext4 или reiser) устранит эту неэффективность (reiser выполняет поиск в каталогах с двоичным алгоритмом разделения, поэтому длинные каталоги обрабатываются гораздо эффективнее, ext4 тоже может это сделать), а также фиксированный лимит на каталог.
источник
Если вы связаны с ext2 / ext3, единственная возможность, которую я вижу, это разделить ваши данные. Найдите критерий, который разбивает ваши данные на управляемые куски одинакового размера.
Если бы речь шла только об изображениях профиля:
Например, кеш SQUID делает это следующим образом:
F / 4b / 353ac7303854033
Каталог верхнего уровня - это первая шестнадцатеричная цифра, второй уровень - следующие две шестнадцатеричные цифры, а имя файла - оставшиеся шестнадцатеричные цифры.
источник
У вас есть лучшее решение - используйте другую файловую систему, доступно множество, многие из которых оптимизированы для различных задач. Как вы указали, ReiserFS оптимизирован для обработки большого количества файлов в каталоге.
Смотрите здесь для сравнения файловых систем.
Просто будьте рады, что вы не застряли с NTFS, которая действительно ужасна для большого количества файлов в каталоге. Я бы порекомендовал JFS в качестве замены, если вы не хотите использовать относительно новую (но очевидно стабильную) ext4 FS.
источник
Изображение профиля маленькое? Как насчет размещения его в базе данных с остальными данными профиля? Возможно, это не лучший вариант для вас, но стоит подумать ...
Вот (старая) техническая статья Microsoft на тему: BLOB или не BLOB .
источник
Я взломал небольшую веб-галерею, где я нашел вариант этой проблемы; У меня «только» было около 30 000 изображений в каталоге кеша, что оказалось довольно медленным (ext2 использует связанные списки для индексов каталогов, насколько я помню).
Я закончил тем, что делал что-то вроде этого:
Это разделит данные на 256 каталогов, что обеспечивает быстрый поиск по каталогам для каждого из трех уровней.
источник
Не немедленный ответ на вашу проблему, но то, на что стоит обратить внимание в будущем - это связанный с OpenBSD проект под названием «Epitome».
Epitome - это механизм, который предоставляет услуги хранения в одном экземпляре, хранения с адресным содержимым и дедупликации.
Все ваши данные хранятся в хранилище данных в виде хешированных блоков, удаляя неуникальные блоки, чтобы сократить использование пространства, и позволяет вам по существу забыть о механизме хранения, поскольку вы можете просто запрашивать содержимое из хранилища данных по UUID.
Epitome в настоящее время является экспериментальным, но есть что посмотреть на будущее.
источник
Как правило, вы хотите избежать наличия каталогов с большим количеством файлов / каталогов в нем. Основная причина заключается в том, что расширение группового символа в командной строке приведет к ошибкам «слишком много аргументов», что приведет к большой боли при попытке работать с этими каталогами.
Найдите решение, которое создает более глубокое, но более узкое дерево, например, путем создания подпапок, как описано другими.
источник
У нас была похожая проблема, решение которой, как упоминалось ранее, заключается в создании иерархии каталогов.
Конечно, если у вас сложное приложение, которое опирается на плоскую структуру каталогов, вам, вероятно, потребуется много исправлений. Поэтому полезно знать, что существует обходной путь, используйте символические ссылки, у которых нет упомянутого ограничения в 32 КБ. Тогда у вас будет достаточно времени, чтобы исправить приложение ...
источник
Почему бы не использовать подход с отметкой времени, а затем иметь опцию переполнения.
Например
Допустим, ваша временная метка: 1366587600
Пропустите последние 2 цифры (иначе это просто немного смешно). Разделите штамп на наборы по 4 (количество каталогов не должно превышать 9999 - если вы хотите, вы можете разделить его по-другому).
Это должно оставить вас с чем-то вроде этого:
Затем также проверьте сумму в dir перед загрузкой, если она получает большое количество загрузок (то есть 32000 + за 100 секунд), затем выполните итерацию каталога по секунде или букве, например:
или
Затем зарегистрируйте отметку времени + букву или полный код пути в БД вместе с пользователем, и вы должны быть установлены.
pathstamp: 1366587600 или 13665876a (если вы используете буквы).
Это приводит к большому количеству каталогов, но это может быть очень полезно для обработки файловых ревизий. Например, если пользователь хочет использовать новое изображение профиля, у вас все еще есть старая версия с меткой времени старой версии на тот случай, если он хочет отменить изменения (она не просто перезаписана).
источник
Я бы предложил решить, сколько максимальных подкаталогов вы хотите (или можете) иметь в родительской папке.
Затем вам нужно преобразовать свой идентификатор пользователя, чтобы они начинались с 1.
Тогда вы можете сделать:
modulo = currentId % numberOfSubdirectories
modulo
теперь будет содержать номер вашего подкаталога, который никогда не будет больше, чемnumberOfSubdirectories
вы выбрали.Делай что хочешь с модулем, хеш это, например.
Также таким образом подкаталоги будут заполняться линейно.
источник