我正在将文件从 LTO-7 磁带上的 tar 存档恢复到本地安装的网络共享。如果我直接恢复到共享,它的运行速度会非常慢(90 MB/s)。当我使用额外的缓冲区时,我获得的最大吞吐量为 280 MB/s。但是我收到管道损坏警告:
mbuffer -s 1M -m 2G -i /dev/st0 | tar -xf -
mbuffer: warning: error during output to <stdout>: Broken pipe
请注意,tar 存档最初是使用 2048 的块系数(即 1MB 块大小)编写的
我猜这意味着 tar 在接收到所有数据之前就退出了(也许缓冲区暂时为空并且 tar 认为数据已经结束?)。
我该如何解决这个问题?即如何确保 tar 等待从缓冲区接收到所有数据?
为什么首先需要缓冲?连接是10G,目标磁盘是非常快的RAID。导致增速放缓的根本原因是什么?
编辑 02/07/2020
我在 tar 命令中添加了阻塞因子,但警告没有出现。
mbuffer -s 1M -m 2G -i /dev/st0 | tar -x -b 2048 -f -
但我仍然想知道如果未指定,为什么我会收到管道损坏警告。
答案1
您的错误消息有一个简单的原因:您使用的 tar 实现在调用之前没有读取所有数据exit()
。
这是由于您没有告诉它真实的磁带块大小而造成的(正如您自己已经发现的那样)。
典型的磁带(QIC 磁带除外)都是阻塞的,为了获得更高的性能,建议使用较大的块大小。不建议与其他人交换大于 126 kB 的块大小,但对于备份,使用 1MB 作为块大小是可以的。
TAR
另一侧也指定为面向工作块,默认块大小为10kB。
EOF
存档的定义是TAR
紧接在最后一个文件之后的两个归零的 512 块(这是tar
需要新标头的位置)。
在 EOF 指示之后,归档处理停止,除非这两个归零块偶然出现在磁带数据的最后 10 kB 中,否则存在未读输入,这就是您收到损坏管道消息的原因。
如果您使用star
,则 FIFO 位于内部tar
,因此,磁带读取代码并且tar
归档处理始终对磁带块大小具有相同的想法。除了速度star
更快之外,这还避免了并非所有输入数据都从tar archive
.
顺便说一句:为了实现最佳流传输,建议 FIFO 缓冲区大小能够以最大磁带速度持续 10-30 秒的数据。直到star
完全增强以支持更大的 FIFO 之前,我建议您致电:
star fs=2000m ...
注:是30年以来的-fifo
默认值。star
另请注意,-shm
不建议在 Linux 上使用类似的选项,因为该功能的内存量有限。
star
绝对比任何其他实现都要快tar
。但请记住,如果您使用的是COW
类似的文件系统ZFS
,或者您的操作系统具有较慢的内核缓冲实现,则建议在提取模式下fsync()
通过禁用调用来提高速度。-no-fsync
这使得star
与其他实现一样“不可靠” tar
;-) 因为无法知道文件在后台存储上是否安全,但这可以将在ZFS
缓冲不良的传统文件系统上的提取速度提高 4 倍。ZFS
然而并没有实现不良缓冲,而只是能够以高代价授予特定的文件系统状态。