У меня есть два сервера (доступ по SSH к Интернету), один с высокопроизводительным процессором и 32 ГБ оперативной памяти. Однако, когда я пытаюсь передать большое количество файлов (около 400 000) с помощью команды:
tar cvf archive.tar folder
Это займет около 2 часов. Когда я выполняю ту же команду на моем компьютере, который имеет аналогичную спецификацию, но меньше оперативной памяти, требуется около 5 минут, чтобы скопировать аналогичный пакет файлов.
У кого-нибудь есть идеи или альтернативы? Командная строка выводит список всех файлов. Я не знаю, вызывает ли это проблемы.
Дисковая фрагментация. Если они - большие файлы, можно использовать filefrag
чтобы проверить, насколько фрагментированный отдельные файлы, но существует другой вид фрагментации, которая имеет тенденцию происходить со многими маленькими файлами: порядок, что имена появляются в каталоге, может полностью отличаться от порядка, что inodes появляются на диске, и тот порядок может полностью отличаться от порядка блоков данных на диске. Это означает при открытии всех файлов в порядке, их имена появляются в каталоге, диск должен искать много и замедляет вещи. Я записал следующий сценарий Python однажды для вычислений корреляции между именами, inodes, и первого блока данных всех файлов в текущем каталоге, таким образом, можно измерить это:
#!/usr/bin/python
import os
from stat import *
import fcntl
import array
names = os.listdir('.')
lastino = 0
name_to_ino_in = 0
name_to_ino_out = 0
lastblock = 0
name_to_block_in = 0
name_to_block_out = 0
iblocks = list()
inode_to_block_in = 0
inode_to_block_out = 0
for file in names :
try :
st = os.stat(file)
except OSError:
continue
if not S_ISREG(st.st_mode) :
continue
if st.st_ino > lastino :
name_to_ino_in += 1
else : name_to_ino_out += 1
lastino = st.st_ino
f = open(file)
buf = array.array('I', [0])
err = fcntl.ioctl(f.fileno(), 1, buf)
if err != 0 :
print "ioctl failed on " + f
block = buf[0]
if block != 0 :
if block > lastblock :
name_to_block_in += 1
else : name_to_block_out += 1
lastblock = block
iblocks.append((st.st_ino,block))
print "Name to inode correlation: " + str(float(name_to_ino_in) / float((name_to_ino_in + name_to_ino_out)))
print "Name to block correlation: " + str(float(name_to_block_in) / float((name_to_block_in + name_to_block_out)))
iblocks.sort()
lastblock = 0
for i in iblocks:
if i[1] > lastblock:
inode_to_block_in += 1
else: inode_to_block_out += 1
lastblock = i[1]
print "Inode to block correlation: " + str(float(inode_to_block_in) / float((inode_to_block_in + inode_to_block_out)))
Старые файловые системы, которые имели много маленьких файлов, добавленных за долгое время, имеют тенденцию входить в плохую форму. Просто копирование всего каталога может привести к месту назначения, являющемуся намного лучше, затем можно удалить оригинал и заменить его копией. Вторая проблема, которая способствует этому, хотя три индексированных функции каталога ext4, которые используются на каталогах со многими файлами в них для создания поиска отдельного имени файла намного быстрее, но по существу полностью рандомизируют порядок имен. Можно проверить, использует ли каталог тройки с lsattr -d
и ищите I
атрибут.
Одна из причин, что я предпочитаю копировать с dump
вместо tar
это, это неуязвимо для этой проблемы, так как это читает все файлы в порядке inode независимо от порядка, имена появляются в каталоге. Это все еще должно спорить с inode для блокирования фрагментации все же. Копия или передача e2defrag
может помочь с этим.