Компьютер: Intel(R) Core(TM)2 Duo CPU E7300 @ 2.66GHz
Жёсткий диск: Seagate Barracuda ES SATA 3.0Gb/s 500Gb
Файловая система: wubi/ntfs/ext3 (использует раздел Widnows)
Операционная система: Ubuntu 8.10
Фаза 1. Создание файлов
Так как свободных инодов было всего 640 тысяч, я принял решение сгенерить полмиллиона файлов. Размер файлов был выбран в 2 килобайта.
Вот скрипт (newLISP):
(module "crypto.lsp")
(make-dir "/home/hilo/testdir")
(change-dir "/home/hilo/testdir")
(define (rand-2k)
(join (map (fn (x) (append (string x) ": " (join
(map string (rand 10 50))))) (sequence 0 37)) "\n"))
(time (dotimes (x 500000)
(write-file (append (crypto:md5 (string (random))) ".txt") (rand-2k))))
Время генерации файлов: 17 минут.
Фаза 2. Тест производительности
; Найти файлы по маске
(directory "." "7.*") ; 0,5с.
; Получить список вообще всех файлов
(directory ".") ; те же 0,5с.
; Отобрать 200 файлов и прочесть их из папки в память:
(map (fn (x) (read-file x)) (directory "." "6666.*")) ; Две секунды
; Прочесть один файл с известным именем:
(read-file "7777cc087494c9e6e474ac9fe6c01dfc.txt") ; 0,013 ms
; Прочесть файл из папки, в которой лежит всего несколько файлов:
(time (read-file "../ffec6ba54ea01fd951dc2433334abd0c.txt")) ; 0,014 ms
Вывод 1: скорость чтения файлов никак не зависит от того, сколько у них соседей в папке.
Вывод 2: файлы читаются мгновенно.
Вывод 3: непонятно, почему чтение 200 предварительно отобранных файлов занимает две секунды -- должно занимать полсекунды. Надо полагать, если сделать отбор имён, подождать две секунды, а потом прочесть их -- чтение займёт не полторы секунды, а несколько миллисекунд.
Фаза 3. Работа со встроенными командами Linux
3.1. Поиск через grep
grep -l "777" 5555* # 3 cекунды
3.2. ls
ls testdir > test.txt # 3 секунды (создался файл на 18 Мb)
3.3. Подсказка имени. Нажатие "Tab" для подсказки подвесило систему примерно на одну минуту, потом всё отвисло.
3.4. rm
rm * вылетел через 40 секунд с ошибкой:
"bash: /bin/rm: Слишком длинный список аргументов."
Выводы. Встроенные средства справляются с 500 тысячами файлов херовато. Самое разумное: сделать сначала ls в файл, а потом работать уже с этим файлом.
Фаза 4. Удаление файлов
(map delete-file (directory ".")) ; две минуты, под бодрое шуршание диска.
На начало эксперимента было свободно 641373 инодов из 856800. После окончания эксперимента свободных инодов стало 641279. Куда зажевались примерно 100 инодов -- неясно. Вероятно, на временные файлы операционной системы и временные файлы newLISP.
Общий вывод. Для серьёзной нагрузки 500 000 файлов -- это довольно натужно. Я бы предпочёл иметь запас по скорости раз в десять от демонстрируемого.
Впрочем, сначала я собираюсь обновить систему до 9.10 и посмотреть, насколько бодро пойдёт работа со встроенной файловой системой.
--- Продолжение ---
Проапгрейдился до 9.10. Файловая система ext4, созданная непосредственно на диске, без всяких промежуточных ntfs. Также немного упростил скрипт:
(make-dir "/tmp/testdir")
(change-dir "/tmp/testdir")
(define (string-append) (apply append (map string (args))))
(define (rand-2k x)
(write-file (string-append x ".txt")
(join (map (fn (x) (append (string x) ": " (join
(map string (rand 10 50))))) (sequence 0 37)) "\n")))
(define (gen-1k y)
(dotimes (x 1000) (rand-2k (string-append y "_" x)))
(println y))
(time (map gen-1k (sequence 0 999)))
Миллион файлов на этот раз создавался 32 минуты. В общем, практически столько же, сколько и в прошлый раз. А вот тайминг (время newLISP сообщает в миллисекундах):
> (time (directory "."))
563,001
> (time (directory "." "666.*"))
572,296 ; Это полсекунды
> (length (directory "."))
1000002
> (time (map read-file (directory "." "666.*")))
9913,617 ; 5 миллисекунд на файл
> (time (map read-file (directory "." "668_.*")))
1186,284 ; 1 миллисекунда на файл
Как видно, скорость поиска в директории увеличилась по сравнению с ntfs в два раза, а вот скорость чтения файлов почему-то сильно скачет. В дальнейших экспериментах скорость чтения одного файла составляла 10-50 миллисекунд на первый заход и примерно 0,02 миллисекунды на чтение кэшированного файла. Файлы, напомню, имеют размер в два килобайта.
Итоговый вывод остался неизменным: работать с миллионом файлов в одной папке можно, если имена файлов известны. Если требуется поиск -- возможны варианты. Полсекунды на поиск иногда уже чересчур.
Удаление заняло примерно полчаса:
(map delete-file (directory "."))
Затем тем же скриптом я успешно нагенерил минут за 40 миллион файлов для Windows:
http://hilocomod.blogspot.com/2010/03/windows.html
А как встроенные команды Linux работают с миллионом файлов?
ОтветитьУдалитьДа нормально работают. Не особо быстро, но, например, ls > filelist.txt выполнился относительно быстро, равно как и rm *
ОтветитьУдалитьВот в Окнах были проблемы со скоростью.
Понятно. Интересный материал, спасибо.
ОтветитьУдалитьСпасибо, пригодилось.
ОтветитьУдалитьСпасибо. Помогло решить задачу.
ОтветитьУдалить