20

我得到了一个 1TB 的稀疏文件,它在 Linux 上实际存储了 32MB 数据。

是否可以“有效地”制作一个包来存储稀疏文件?该软件包应在另一台计算机上解压缩为 1TB 稀疏文件。理想情况下,“包”应该在 32MB 左右。

注意:可能的解决方案是使用“tar”:https ://wiki.archlinux.org/index.php/Sparse_file#Archiving_with_.60tar.27

但是,对于 1TB 的稀疏文件,虽然 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

包含 0 字节数据的 1TB 文件 sparse-1 可以通过“tar”归档到 10KB tar 球或通过 gzip 压缩到 ~1GB 文件。gzip 花费的时间大约是 tar 使用时间的 2 倍。

从比较来看,'tar' 似乎比 gzip 好。

但是,对于包含 0 字节数据的稀疏文件来说,96 分钟太长了。

编辑 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+ cporscp应该比直接更快。rsync

编辑 3

感谢@mvp 指出较新内核中的 SEEK_HOLE 功能。(我以前在 2.6.32 Linux 内核上工作)。

注意:bsdtar 版本 >=3.0.4 是必需的(在这里查看:http ://ask.fclose.com/4/how-to-efficiently-archive-a-very-large-sparse-file?show=299#c299 )。

在较新的内核和 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
4

4 回答 4

29

简短的回答: 使用bsdtarGNU tar(1.29 或更高版本)创建档案,使用 GNU tar(1.26 或更高版本)将它们提取到另一个盒子上。

长答案: 这个工作有一些要求。

首先,Linux 必须至少是内核 3.1(Ubuntu 12.04 或更高版本可以),因此它支持SEEK_HOLE功能。

然后,您需要可以支持此系统调用的 tar 实用程序。GNUtar从 1.29 版(于 2016/05/16 发布,自 Ubuntu 18.04 起默认存在)或bsdtar自 3.0.4 版(自 Ubuntu 12.04 起可用)开始支持它 - 使用sudo apt-get install bsdtar.

虽然bsdtar(使用libarchive)很棒,但不幸的是,它在解压缩时并不是很聪明 - 它愚蠢地要求目标驱动器上的可用空间至少与解压缩文件大小一样多,而不考虑漏洞。GNUtar将有效地解压这些稀疏档案,并且不会检查这种情况。

这是来自 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

# Or, use gnu tar if version is later than 1.29:
$ time tar cSvfz sparse-gnutar.tar.gz 1tb
1tb

real    0m0.005s
user    0m0.006s
sys 0m0.000s

$ ls -l
-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
-rw-rw-r-- 1 autouser autouser           134 Nov  7 01:43 sparse-gnutar.tar.gz
$

就像我上面说的,不幸的是,bsdtar除非你有 1TB 的可用空间,否则解压将不起作用。但是,任何版本的 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
于 2012-11-07T10:01:08.117 回答
5

我意识到这个问题已经很老了,但这里有一个更新,可能对其他像我一样在这里找到方式的人有所帮助。

值得庆幸的是,mvp 的出色答案现在已经过时了。根据 GNU tar 发行说明,SEEK_HOLE/SEEK_DATA 是在 2016 年 5 月 16 日发布的 v. 1.29 中添加的。(并且现在 GNU tar v. 1.30 在 Debian stable 中成为标准,可以安全地假设 tar 版本 ≥ 1.29 几乎在任何地方都可用。)

因此,现在处理稀疏文件的方法是使用系统上安装的任何 tar(GNU 或 BSD)来归档它们,提取时也是如此。

此外,对于实际包含一些数据的稀疏文件,是否值得使用压缩(即数据可压缩到足以节省大量磁盘空间,并且节省的磁盘空间值得压缩它所需的大量时间和 CPU 资源) :

  • 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 CPU 的小型家用服务器上,使用pbzip2vsbzip2减少了大约 25% 或 30% 的时间。

无论是否压缩,这将为您提供一个不需要任何特殊稀疏文件处理的存档,占用大约原始稀疏文件的“真实”大小(如果压缩则更少),并且可以随意移动而不用担心关于不同实用程序的稀疏文件功能之间的不一致。例如:cp将自动检测稀疏文件并做正确的事情,rsync如果您使用该-S标志,将正确处理稀疏文件,并且scp没有稀疏文件选项(它将消耗带宽,为所有孔复制零并且生成的副本将是非稀疏文件,其大小是原始文件的“表观”大小);但是它们当然都可以很好地处理 tar 存档——无论它是否包含稀疏文件——而无需任何特殊标志。

补充笔记

  1. 提取时,tar将自动检测使用创建的存档,-S因此无需指定它。
  2. 使用创建的存档pbzip2存储在块中。这导致归档文件比bzip2使用的文件稍大,但也意味着提取可以是多线程的,这与使用bzip2.
  3. pbzip2并且bzip2将可靠地提取彼此的档案而不会出现错误或损坏。
于 2019-09-13T17:27:01.730 回答
2

一个相关的问题,也许rsync会起作用:

rsync --sparse sparse-1 sparse-1-copy
于 2012-11-07T08:51:54.190 回答
-3

您肯定在寻找压缩工具,例如tarlzma、或. 根据这个网站,速度非常快,同时仍然具有相当好的压缩比:bzip2ziprarlzma

http://blog.terzza.com/linux-compression-comparison-gzip-vs-bzip2-vs-lzma-vs-zip-vs-compress/

您还可以通过将压缩级别设置为较低的值来调整压缩的速度/质量比,尝试一下以找到最适合的级别

http://linux.die.net/man/1/unlzma

于 2012-11-06T14:18:35.623 回答