![多个 tar 进程同时写入同一个归档文件](https://linux22.com/image/39041/%E5%A4%9A%E4%B8%AA%20tar%20%E8%BF%9B%E7%A8%8B%E5%90%8C%E6%97%B6%E5%86%99%E5%85%A5%E5%90%8C%E4%B8%80%E4%B8%AA%E5%BD%92%E6%A1%A3%E6%96%87%E4%BB%B6.png)
我在 Linux 集群上运行许多任务。每个任务都会创建许多输出文件。当所有任务完成后,我运行类似tar cf foo.tar output_files/
创建tar
存档的操作。这是一个非常缓慢的过程,因为有数千个文件和目录。
有没有办法在创建输出文件时并行执行此操作?
是否可以有多个tar
进程,分布在多台机器上,同时将它们的文件添加到同一个存档中?
集群有一个共享文件系统。
我对压缩不感兴趣,因为它会进一步减慢速度,并且因为所有输入文件本身都已经被压缩。理想情况下,输出是一个tar
文件,但我也会考虑其他存档格式。
答案1
您不能将多个进程添加到同一个 tar 存档(或任何其他常用的存档格式,无论压缩与否)。每个文件都是连续存储的,无法在文件中插入数据,只能追加或覆盖,因此继续写入不是最后一个文件会覆盖后续文件。
如果您提前知道文件大小,则可以在 tar 存档中保留该大小并让程序继续写入。这需要大量的编码:这是一件非常不寻常的事情。
Unix 有一项功能旨在容纳一组独立写入的文件。它称为目录。
在极少数情况下,您可以从目录上的未压缩存档中获得任何内容。在某些情况下,阅读速度可能会稍快一些;这是目录格式(其中每个文件条目都是指向其内容的指针)的固有结果,而不是存档格式(其中每个文件条目直接是其内容),这正是使分段构建目录成为可能的原因。将目录树转换为存档是需要按顺序完成的后处理。
答案2
您可以在创建所有输出文件之前开始创建最终tar
文件:也许这可以实现您想要的速度。
您可以这样调用 tar:
tar -cf foo.tar -T file-list
file-list
将是一个 FIFO。你需要一个脚本来检测
源目录中的新文件 (
inotifywatch
)当每个新文件完成时 (
fuser
)
如果文件完成,则其路径将写入 FIFO。也许不创建具有完全混合路径的存档是有用的。您可以从获取第一个输入文件的目录开始,仅在最后一个文件完成后添加新目录(在相应进程完成后创建一个标志文件)。第一种方法的优点是文件可能完全在缓存中。
答案3
GNU tar 有 --append:
tar -f foo.tar --append newfiles
不幸的是它读取了完整的 tar 文件。