我有一个运行以下命令的备份脚本:
tar -c dir1 dir2 | xz -9 -T0 | gpg -c --batch --passphrase xxx | aws s3 ...
返回值始终相同:tar
失败141
(broken pipe
错误)并xz
返回137
(没有其他错误消息,即使在详细模式下也是如此)。
该脚本经过测试,可以root
在其他服务器上运行并且运行良好。最初我认为我正在备份的数据可能已损坏并删除了备份目录(这是一个rsnapshot
文件夹)中的一些套接字文件,但这也没有帮助。
有谁知道问题可能是什么?
编辑:如果我xz
从管道中取出它就可以了。
答案1
长话短说:尝试
xz -9 -T{number of CPU cores - 1} --memlimit={reasonable amount of RAM}
或者替换xz -T0
为zstd
以更高的速度获得类似的压缩率,甚至无需使用多个核心。
这里发生的情况很可能是您xz
被操作系统的内存不足杀手杀死,以便其余的可以生存。这当然会破坏管道。 (这仍然有点令人惊讶;通常xz -9
最多需要 700 MB 的 RAM,每个核心的内存并不多)。您可以尝试将--memlimit=1000MiB
RAM 使用量限制为 1000 MiB(或其他)。然而,如果这解决了问题,那就意味着你的“合理的CPU数量”无法满足你的-9
压缩设置的需要,而xz
不得不选择一个较低的。所以,你的问题可能是你的 RAM 太少,-9
每个 CPU 核心的线程太少,除了减少其中任何一个之外,没有什么可以解决这个问题。
-T0
意味着“使用与 CPU 核心一样多的线程”,这是适得其反的,因为您获取结果数据,并将其通过 GPG 传递(GPG 本身效率并不太高,而且很可能需要大约一个 CPU 核心),并通过该aws
命令,该命令本身将对连接进行 TLS 加密(并且很可能尝试使用 DEFLATE 本身来减少数据量但不成功)。
因此,在极端情况下,-T
最多应将 CPU 核心数减一使用。
xz
一般来说,一开始可能不使用。这是一个出色的压缩机,当然,但它是难以置信慢的。我知道您可能按 GB 存储付费,但是:
zstd
以低得多的资源使用率/更高的吞吐量实现类似的结果。
例如,根据我的经验,xz -T0 -6
用混合图片/源代码/二进制备份替换会zstd -15
产生大 5% 的文件,但压缩速度大约是原来的 2 倍,虽然我没有使用 zstd 的多线程(在 8 核机器上)。
如果您愿意/需要,您仍然可以启用多线程,但看到您还在为 AWS 传输执行 gpg 和 TLS,您可能不(往上看)。
答案2
我建议删除-T0
或在其中放置一个 0 以外的数字(例如 CPU 的一半或更少)。 xz 几乎肯定内存不足并被 OOM 杀死。使用-9
也会增加内存使用。