Мы хотели бы хранить миллионы текстовых файлов в файловой системе Linux, чтобы иметь возможность архивировать и обслуживать произвольную коллекцию в качестве службы. Мы пробовали другие решения, такие как база данных ключ / значение, но наши требования к параллелизму и параллелизму делают использование собственной файловой системы лучшим выбором.
Самый простой способ - хранить все файлы в папке:
$ ls text_files/
1.txt
2.txt
3.txt
это должно быть возможно в файловой системе EXT4 , у которой нет ограничений на количество файлов в папке.
Два процесса FS будут:
- Записать текстовый файл из веб-скрипта (не должно зависеть от количества файлов в папке).
- Zip выбранные файлы, заданные списком имен файлов.
Мой вопрос заключается в том, повлияет ли хранение до десяти миллионов файлов в папке на производительность вышеупомянутых операций или общую производительность системы, чем создание дерева подпапок для файлов, в которых они будут жить?
источник
dir_index
, которое по умолчанию часто включено, ускорит поиск, но может ограничить количество файлов в каталоге.ls -l
или что-то еще, чтоstat
каждый инод в каталоге (например,bash
завершение глобализации / табуляции) будет искусственно быстрее чем после некоторого износа (удалите несколько файлов, напишите несколько новых). ext4 мог бы справиться с этим лучше, чем XFS, потому что XFS динамически распределяет пространство для инодов и данных, так что я думаю, что вы можете получить иноды более разбросанными. (Но это чистое предположение, основанное на очень небольших подробных знаниях; я едва использовал ext4). Перейти сabc/def/
subdirs.ZipOutputStream
, обгонит практически любую свободную собственную файловую систему Linux - я сомневаюсь, что вы хотите платить за GPFS от IBM. Цикл для обработки результирующего набора JDBC и создания этого zip-потока, вероятно, состоит всего из 6-8 строк кода Java.Ответы:
Команда
ls
, или даже завершение TAB или расширение подстановочного знака оболочкой, обычно представляют свои результаты в алфавитно-цифровом порядке. Для этого необходимо прочитать весь каталог и отсортировать его. С десятью миллионами файлов в одном каталоге эта операция сортировки займет немалое количество времени.Если вы можете противостоять желанию TAB-завершения и, например, написать имена файлов, которые будут полностью заархивированы, проблем не должно быть.
Другая проблема с подстановочными знаками может быть расширением подстановочных знаков, возможно, производящим больше имен файлов, чем поместится в командной строке максимальной длины. Типичная максимальная длина командной строки будет более чем достаточной для большинства ситуаций, но когда мы говорим о миллионах файлов в одном каталоге, это уже не безопасное предположение. Когда максимальная длина командной строки будет превышена в расширении с подстановочными знаками, большинство оболочек просто завершат работу всей командной строки, не выполнив ее.
Это можно решить, выполнив групповые операции с помощью
find
команды:или подобный синтаксис, когда это возможно. Он
find ... -exec ... \+
автоматически примет во внимание максимальную длину командной строки и выполнит команду столько раз, сколько потребуется, при этом подгоняя максимальное количество имен файлов для каждой командной строки.источник
ls
команда не узнают, что список каталогов уже отсортирован, им все равно потребуется время для запуска алгоритма сортировки. И, кроме того, пользовательское пространство может использовать локализованный порядок сортировки (LC_COLLATE), который может отличаться от того, что файловая система может делать внутри.Это опасно близко к основанному на мнении вопросу / ответу, но я постараюсь изложить некоторые факты с моими мнениями.
mv * /somewhere/else
), может не удастся успешно развернуть подстановочный знак, или результат может быть слишком большим для использования.ls
для перечисления очень большого количества файлов потребуется больше времени, чем для небольшого количества файлов.Одна из рекомендаций - разделить имя файла на два, три или четыре символа и использовать их в качестве подкаталогов. Например,
somefilename.txt
может быть сохранен какsom/efi/somefilename.txt
. Если вы используете числовые имена, разделите их справа налево, а не слева направо, чтобы обеспечить более равномерное распределение. Например,12345.txt
может быть сохранен как345/12/12345.txt
.Вы можете использовать эквивалент,
zip -j zipfile.zip path1/file1 path2/file2 ...
чтобы избежать включения промежуточных путей подкаталогов в ZIP-файл.Если вы обслуживаете эти файлы с веб-сервера (я не совсем уверен, что это актуально), тривиально скрыть эту структуру в пользу виртуального каталога с правилами перезаписи в Apache2. Я бы предположил, что то же самое верно для Nginx.
источник
*
Расширение будет успешным , если вы бежите из памяти, но если вы не поднять предел STACKSIZE (на Linux) или использовать оболочку , гдеmv
есть встроенный или может быть встроенным (ksh93, ЗШ), тоexecve()
системный вызов может произойти сбой с ошибкой E2BIG.zip -j - ...
и передавать поток вывода напрямую через сетевое соединение клиентаzip -j zipfile.zip ...
. Запись фактического zip-файла на диск означает, что путь к данным считывается с диска-> сжатие-> запись на диск-> чтение с диска-> отправка клиенту. Это может утроить ваши требования к вводу-выводу диска по сравнению с чтением с диска-> сжимать-> отправлять клиенту.Я управляю веб-сайтом, который обрабатывает базу данных для фильмов, телевидения и видеоигр. Для каждого из них есть несколько изображений с ТВ, содержащих десятки изображений на шоу (т.е. снимки эпизодов и т. Д.).
Там в конечном итоге много файлов изображений. Где-то в диапазоне 250000+. Все они хранятся в смонтированном блочном хранилище, где время доступа разумно.
Моя первая попытка хранения изображений была в одной папке как
/mnt/images/UUID.jpg
Я столкнулся со следующими проблемами.
ls
через удаленный терминал просто зависнет. Процесс пошел бы зомби иCTRL+C
не сломал бы его.ls
команда быстро заполнит выходной буфер иCTRL+C
не остановит бесконечную прокрутку.В итоге мне пришлось хранить файлы в подпапках, используя время создания для создания пути. Такие как
/mnt/images/YYYY/MM/DD/UUID.jpg
. Это решило все вышеперечисленные проблемы и позволило мне создавать zip-файлы с указанием даты.Если единственным идентификатором файла, который у вас есть, является числовое число, и эти числа, как правило, выполняются последовательно. Почему бы не сгруппировать их
100000
,10000
а1000
.Например, если у вас есть файл с именем
384295.txt
путь будет:Если вы знаете, вы достигнете нескольких миллионов. Используйте
0
префиксы для 1 000 000источник
Для создания нового файла требуется сканирование файла каталога на наличие достаточного свободного места для новой записи каталога. Если на диске недостаточно места для хранения новой записи каталога, она будет помещена в конец файла каталога. По мере увеличения количества файлов в каталоге время сканирования каталога также увеличивается.
Пока файлы каталогов остаются в системном кеше, производительность от этого не будет плохой, но если данные будут освобождены, чтение файла каталога (обычно сильно фрагментированного) с диска может занять довольно много времени. SSD улучшает это, но для каталога с миллионами файлов, все еще может быть заметное снижение производительности.
Это также может потребовать дополнительного времени в каталоге с миллионами файлов. В файловой системе с хешированными записями каталога (например, EXT4) эта разница минимальна.
Дерево подпапок не имеет ни одного из перечисленных выше недостатков производительности. Кроме того, если базовая файловая система изменена, чтобы не иметь хэшированных имен файлов, методология дерева все равно будет работать хорошо.
источник
Во-первых: не позволяйте 'ls' сортировать с помощью 'ls -U', возможно, обновите ваш ~ / bashrc, чтобы он имел 'alias ls = "ls -U" или что-то подобное.
Для вашего большого набора файлов вы можете попробовать это следующим образом:
создать набор тестовых файлов
посмотреть, если много имен файлов вызывают проблемы
используйте xargs parmeter-batching и zip (по умолчанию) для добавления файлов в zip, чтобы избежать проблем.
Это сработало хорошо:
источник