Почему делает перемещение некоторых файлов в папке, занимают больше времени, чем перемещение целой папки?

У меня есть миллионы изображений на моем облачном сервере человечности. Когда я перемещаю полную папку, содержащую 12 миллионов использований изображений mv команда, это происходит почти мгновенно. Однако, когда я mv только изображения (не папка) затем это занимает время. Существует ли способ переместить все изображения так же быстро как папки?

Это - то, что происходит:

  1. папка src имеет 12 миллионов изображений, и я перемещаю это в dst использование папки

    $ mv  src ../dst
    

    Сразу происходит

  2. Внутри папка src я делаю это для перемещения:

    find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ {} +
    

    Это занимает время.

Существует ли способ ускорить второй процесс?

21
задан 6 July 2016 в 04:44

4 ответа

TL; DR: нет

Для меньшей суммы файлов Вам не было бы нужно find но, даже в этом упрощенном и меньшем случае, если Вы просто

mv *.jpg ../../dst/

потребуется больше времени, чем перемещение целого каталога сразу.


Почему? Точка должна понять что mv делает.

Кратко говорящий, mv перемещает число (который определяет каталог или файл) от inode (каталог, содержащий его) к другому, и эти индексы обновляются в журнале файловой системы или в FAT (если файловая система реализована таким способом).

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

Так, когда Вы mv один каталог, Вы делаете эту операцию одно время.

Но когда Вы перемещаете 1 миллион файлов, Вы делаете эту операцию 1 миллион раз.

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

50
ответ дан 23 November 2019 в 01:38

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

Однако можно ускорить его от того, что Вы имеете теперь.

Ваша команда находки выполняет должностное лицо однажды для каждого файла. Таким образом, это запускается mv миллион раз команды 12 для 12 миллионов файлов. Это может быть улучшено двумя способами.

  • Добавьте плюс в конец:
    find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ +
    Проверьте страницу справочника, чтобы удостовериться, что она поддерживается в Вашей версии find. Эффект должен состоять в том, чтобы выполнить серию mv команды со столькими именами файлов, сколько будет соответствовать на каждой командной строке.

  • Использовать find и xargs вместе.
    find -maxdepth 1 -name '*.jpg' -print0 | xargs -0 mv -t ../../dst/
    -print0 будет использовать NUL, иначе нулевые байты для разделения имен файлов. Это плюс xargs -0 решает любые проблемы xargs иначе имел бы с пробелами в именах файлов. xargs команда прочитает список имен файлов от find управляйте и работайте mv команда на стольких именах файлов, сколько будет соответствовать.

13
ответ дан 23 November 2019 в 01:38

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

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

mv src ../dst перемещает единственную запись списка из каталога . к каталогу ../dst, таким образом, это быстро.

find -maxdepth 1 -name '*.jpg' -exec mv -t ../../dst/ должен переместить миллионы записей, таким образом, это медленнее. Это может потенциально быть ускорено, если Вы звоните mv только однажды и не однажды на файл, и mv сама команда может быть оптимизирована для перемещения нескольких записей каталога за один шаг, но нет никакого способа сделать ее с такой скоростью, как, когда Вы перемещаете единственный каталог.

7
ответ дан 23 November 2019 в 01:38

Упрощенный ответ

перемещение файла сделано, 3 шага:

  • добавьте () ссылку на файл к inode списку папки назначения
  • проверьте, была ли ссылка успешно добавлена
  • удалите () ссылку из списка inodes исходной папки, если проверка выше имела успех.

этот процесс является тем же для файла или папки.
и очевидно выполнение этого для 1 файла равняется 100 быстрее, чем выполнение его для 100 файлов.

man link добавление ()
man unlink удаление ()
mv просто использование те две команды выше и добавляет промежуток проверки для предотвращения потери данных.

4
ответ дан 23 November 2019 в 01:38

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

Похожие вопросы: