Копирование файла размером 1 ТБ
Я получил разреженный файл размером 1 ТБ, в котором хранится 32 МБ данных в Linux.
Можно ли "эффективно" сделать пакет для хранения разреженного файла? Пакет должен быть распакован, чтобы быть редким файлом размером 1 ТБ на другом компьютере. В идеале, "пакет" должен быть около 32 МБ.
Примечание: по возможному решению стоит использовать "tar": https://wiki.archlinux.org/index.php/Sparse_file
Тем не менее, для разреженного файла размером 1 ТБ, хотя tar-шар может быть небольшим, архивирование разреженного файла займет слишком много времени.
Редактировать 1
Я протестировал tar и gzip, и результаты таковы (обратите внимание, что этот разреженный файл содержит данные размером 0 байт).
$ du -hs sparse-1
0 sparse-1
$ ls -lha sparse-1
-rw-rw-r-- 1 user1 user1 1.0T 2012-11-03 11:17 sparse-1
$ time tar cSf sparse-1.tar sparse-1
real 96m19.847s
user 22m3.314s
sys 52m32.272s
$ time gzip sparse-1
real 200m18.714s
user 164m33.835s
sys 10m39.971s
$ ls -lha sparse-1*
-rw-rw-r-- 1 user1 user1 1018M 2012-11-03 11:17 sparse-1.gz
-rw-rw-r-- 1 user1 user1 10K 2012-11-06 23:13 sparse-1.tar
Файл sparse-1 объемом 1 ТБ, содержащий 0-байтовые данные, может быть заархивирован tar с помощью tar-шара размером 10 КБ или сжат с помощью gzip в файл размером ~1 ГБ. Gzip занимает примерно 2 раза больше времени, чем использует tar.
Из сравнения "tar" кажется лучше, чем gzip.
Однако 96 минут слишком длинны для разреженного файла, который содержит данные 0 байтов.
Редактировать 2
rsync
кажется, закончить копирование файла в более короткие сроки, чем tar
но меньше чем gzip
:
$ time rsync --sparse sparse-1 sparse-1-copy
real 124m46.321s
user 107m15.084s
sys 83m8.323s
$ du -hs sparse-1-copy
4.0K sparse-1-copy
Следовательно, tar
+ cp
или же scp
должно быть быстрее, чем напрямую rsync
для этого крайне редкого файла.
Редактировать 3
Спасибо @mvp за указание на функциональность SEEK_HOLE в более новом ядре. (Ранее я работал над ядром Linux 2.6.32).
Примечание: требуется версия bsdtar>=3.0.4 (проверьте здесь: http://ask.fclose.com/4/how-to-efficiently-archive-a-very-large-sparse-file?show=299).
В более новом ядре и выпуске Fedora (17), tar
а также cp
очень эффективно обрабатывает разреженный файл.
[zma@office tmp]$ ls -lh pmem-1
-rw-rw-r-- 1 zma zma 1.0T Nov 7 20:14 pmem-1
[zma@office tmp]$ time tar cSf pmem-1.tar pmem-1
real 0m0.003s
user 0m0.003s
sys 0m0.000s
[zma@office tmp]$ time cp pmem-1 pmem-1-copy
real 0m0.020s
user 0m0.000s
sys 0m0.003s
[zma@office tmp]$ ls -lh pmem*
-rw-rw-r-- 1 zma zma 1.0T Nov 7 20:14 pmem-1
-rw-rw-r-- 1 zma zma 1.0T Nov 7 20:15 pmem-1-copy
-rw-rw-r-- 1 zma zma 10K Nov 7 20:15 pmem-1.tar
[zma@office tmp]$ mkdir t
[zma@office tmp]$ cd t
[zma@office t]$ time tar xSf ../pmem-1.tar
real 0m0.003s
user 0m0.000s
sys 0m0.002s
[zma@office t]$ ls -lha
total 8.0K
drwxrwxr-x 2 zma zma 4.0K Nov 7 20:16 .
drwxrwxrwt. 35 root root 4.0K Nov 7 20:16 ..
-rw-rw-r-- 1 zma zma 1.0T Nov 7 20:14 pmem-1
Я использую ядро 3.6.5:
[zma@office t]$ uname -a
Linux office.zhiqiangma.com 3.6.5-1.fc17.x86_64 #1 SMP Wed Oct 31 19:37:18 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
5 ответов
Краткий ответ: Использование bsdtar
создавать архивы и GNU tar
чтобы извлечь их на другую коробку.
Длинный ответ: Есть некоторые требования, чтобы это работало.
Во-первых, Linux должен быть как минимум с ядром 3.1 (Ubuntu 12.04 или более поздняя версия), поэтому он поддерживает функциональность SEEK_HOLE.
Затем вам нужна утилита tar, которая может поддерживать этот системный вызов. На данный момент GNU tar
не поддерживает, но bsdtar
делает - установите его используя sudo apt-get install bsdtar
,
В то время как bsdtar
(который использует libarchive
) - это круто, к сожалению, он не очень умен, когда дело доходит до неперехвата - ему тупо нужно иметь как минимум столько же свободного места на целевом диске, сколько и размер файла без изменений, без учета дыр. GNU tar
эффективно разархивирует такие редкие архивы и не будет проверять это условие.
Это журнал из Ubuntu 12.10 (ядро Linux 3.5):
$ dd if=/dev/zero of=1tb seek=1T bs=1 count=1
1+0 records in
1+0 records out
1 byte (1 B) copied, 0.000143113 s, 7.0 kB/s
$ time bsdtar cvfz sparse.tar.gz 1tb
a 1tb
real 0m0.362s
user 0m0.336s
sys 0m0.020s
$ ls -l
total 8
-rw-rw-r-- 1 autouser autouser 1099511627777 Nov 7 01:43 1tb
-rw-rw-r-- 1 autouser autouser 257 Nov 7 01:43 sparse.tar.gz
$
Как я уже сказал выше, к сожалению, bsdtar
не будет работать, если у вас нет 1 ТБ свободного места. Тем не менее, GNU tar работает отлично, чтобы распаковать такие sparse.tar
:
$ rm 1tb
$ time tar -xvSf sparse.tar.gz
1tb
real 0m0.031s
user 0m0.016s
sys 0m0.016s
$ ls -l
total 8
-rw-rw-r-- 1 autouser autouser 1099511627777 Nov 7 01:43 1tb
-rw-rw-r-- 1 autouser autouser 257 Nov 7 01:43 sparse.tar.gz
Я понимаю, что этот вопрос очень старый, но вот обновление, которое может быть полезно для других, которые попадают сюда так же, как и я.
К счастью, отличный ответ mvp теперь устарел. Согласно примечаниям к выпуску GNU tar, SEEK_HOLE/SEEK_DATA был добавлен в версии 1.29, выпущенной 16 мая 2016 года. (А поскольку GNU tar v. 1.30 сейчас является стандартом в стабильной версии Debian, можно с уверенностью предположить, что tar версии ≥ 1.29 доступен почти везде.)
Таким образом, теперь способ обрабатывать разреженные файлы - это архивировать их с помощью любого tar (GNU или BSD), установленного в вашей системе, и то же самое для распаковки.
Кроме того, для разреженных файлов, которые на самом деле содержат некоторые данные, стоит ли использовать сжатие (т. Е. Данные достаточно сжимаемы, чтобы сэкономить значительное дисковое пространство, а экономия дискового пространства стоит вероятного значительного времени и ресурсов процессора, необходимых для их сжатия):
tar -cSjf <archive>.tar.bz2 /path/to/sparse/file
оба будут использовать функциональность tar SEEK_HOLE для быстрого и эффективного архивирования разреженного файла, а также использовать bzip2 для сжатия фактических данных.tar --use-compress-program=pbzip2 -cSf <archive>.tar.bz2 /path/to/sparse/file
, Как упомянуто в комментарии Marcin, в будет делать то же самое, а также с использованием нескольких ядер для выполнения этой задачи сжатия.
На моем маленьком домашнем сервере с четырехъядерным процессором Atom, используя pbzip2
против bzip2
время сократилось примерно на 25 или 30%.
Со сжатием или без него, это даст вам архив, который не требует какой-либо специальной обработки разреженных файлов, занимает примерно `` реальный '' размер исходного разреженного файла (или меньше в случае сжатия) и может перемещаться, не беспокоясь. о несоответствии между возможностями разреженных файлов разных утилит. Например:cp
автоматически обнаружит разреженные файлы и сделает все правильно, rsync
будет правильно обрабатывать разреженные файлы, если вы используете -S
флаг и scp
не имеет опции для разреженных файлов (он будет использовать нули при копировании полосы пропускания для всех дыр, и полученная копия будет не разреженным файлом, размер которого равен "кажущемуся" размеру оригинала); но все они, конечно же, отлично справятся с tar-архивом - независимо от того, содержит он разреженные файлы или нет - без каких-либо специальных флагов.
Дополнительные примечания
- При извлечении
tar
автоматически обнаружит архив, созданный с помощью-S
поэтому указывать его не нужно. - Архив, созданный с помощью
pbzip2
хранится кусками. Это приводит к тому, что архив немного больше, чем если быbzip2
используется, но также означает, что извлечение может быть многопоточным, в отличие от архива, созданного с помощьюbzip2
. pbzip2
а такжеbzip2
надежно извлекают архивы друг друга без ошибок или повреждений.
Из смежного вопроса, может быть rsync
буду работать:
rsync --sparse sparse-1 sparse-1-copy
Оба(начиная с версии 5.0.0 ) и(начиная с версии 0.7.0) инструменты сжатия поддерживают разреженные файлы.
Для быстрого теста я создал разреженный файл размером 10 ГБ с 5 МБ фактических (случайных) данных в самом конце.
% dd if=/dev/random of=file.img bs=5M count=1 seek=2047
1+0 records in
1+0 records out
5242880 bytes (5,2 MB, 5,0 MiB) copied, 0,0223623 s, 234 MB/s
% du -h --apparent-size file.img
10G file.img
% du -h file.img
5,0M file.img
% sha1sum file.img
eb8104d1c1f8ac9dd502f7010f1625b283a8e423 file.img
xz
смог сжать его в неразреженный файл размером 6,5 МБ за 3 минуты 36 секунд и распаковать обратно в тот же разреженный файл размером 10 ГБ за 16 секунд. Здесь я использовал однопоточный режим по умолчанию, он также работает (и немного быстрее) в многопоточном режиме.
% xz --version
xz (XZ Utils) 5.2.5
liblzma 5.2.5
% xz file.img
% du -h --apparent-size file.img.xz
6,5M file.img.xz
% du -h file.img.xz
6,5M file.img.xz
% sha1sum file.img.xz
685d2fe4cd19a02eb4a17f77f9a89decf6c59b73 file.img.xz
% unxz file.img.xz
% du -h --apparent-size file.img
10G file.img
% du -h file.img
5,0M file.img
% sha1sum file.img
eb8104d1c1f8ac9dd502f7010f1625b283a8e423 file.img
zstd
может сделать то же самое, но немного лучше и намного быстрее. Он сжал разреженный файл в неразреженный файл размером 5,4 МБ за 4 секунды и распаковал его обратно в тот же разреженный файл размером 10 ГБ за 2 секунды.
% zstd --version
*** zstd command line interface 64-bits v1.5.2, by Yann Collet ***
% zstd --rm file.img
file.img : 0.05% ( 10.0 GiB => 5.32 MiB, file.img.zst)
% du -h --apparent-size file.img.zst
5,4M file.img.zst
% du -h file.img.zst
5,4M file.img.zst
% sha1sum file.img.zst
b1dda0c1f83bdfbf2094f1d39810edb379602cb3 file.img.zst
% unzstd --rm file.img.zst
file.img.zst : 10737418240 bytes
% du -h --apparent-size file.img
10G file.img
% du -h file.img
5,0M file.img
% sha1sum file.img
eb8104d1c1f8ac9dd502f7010f1625b283a8e423 file.img
Вы определенно ищете инструмент сжатия, такой как tar
, lzma
, bzip2
, zip
или же rar
, По данным этого сайта, lzma
довольно быстро, но при этом имеет хорошую степень сжатия:
http://blog.terzza.com/linux-compression-comparison-gzip-vs-bzip2-vs-lzma-vs-zip-vs-compress/
Вы также можете настроить соотношение скорости и качества сжатия, установив уровень сжатия на низкое значение, поэкспериментировав немного, чтобы найти уровень, который работает лучше всего.