虚拟只写文件系统,用于将文件存储在归档中


8

我有一个令人尴尬的并行过程,该过程会创建大量几乎(但不是完全)相同的文件。有没有一种方法可以“即时”归档文件,以使数据不会消耗比所需更多的空间?

该进程本身接受命令行参数,并将创建的每个文件的名称打印到stdout。我正在调用它,parallel --gnu它负责分配输入(来自另一个进程)并收集输出:

arg_generating_process | parallel --gnu my_process | magic_otf_compressor

管道第一部分的简单示例bash

for ((f = 0; $f < 100000; f++)); do touch $f; echo $f; done

怎么能magic_otf_compressor是什么样子?应该将每个输入行都视为文件名,然后将每个文件复制到压缩.tar存档中(已处理所有文件的存档!),然后将其删除。(实际上,打印每个已处理文件的名称就足够了,另一个| parallel --gnu rm可以负责删除文件。)

有没有这样的工具?我不考虑单独压缩每个文件,这会浪费太多空间。我调查了archivemount(将文件系统保留在内存中->不可能,我的文件太大和太多)和avfs(无法使其与FUSE一起使用)。我错过了什么?

我距离自己入侵这样的工具仅一步之遥,但必须有人做过……

编辑:从本质上讲,我认为我正在寻找一个stdin前端libtar(而不是从命令行tar读取参数的命令行前端)。


您是否考虑过以具有本机压缩的格式编写文件?例如,可以使用gzip或szip压缩来压缩hdf5。Hdf5还支持MPI,因此它可以很好地解决那些令人尴尬的并行问题。
casey 2014年

2
如果您要压缩和重复数据删除,则可以想到zfs。
斯特凡Chazelas

@casey:是HTML,但是我想我可以使用HDF5容器。还没有考虑这个。
krlmlr 2014年

@StephaneChazelas:这可以在用户环境中实现吗?
krlmlr 2014年

Answers:


1

似乎tar想预先知道所有文件名。因此,它不那么动态,而更多。cpio似乎没有这个问题:

| cpio -vo 2>&1 > >(gzip > /tmp/arc.cpio.gz) | parallel rm

谢谢。因此,即使RTFM还不够;-)我什tar至查看的代码,发现有一个函数可以返回下一个要处理的文件名,这使我再次阅读了文档。-那么,它stdoutgzip通过流程替换定向到流程的,并stderr重定向到stdout管道中下一步处理的流程?
krlmlr 2014年

对。>>()构造并非在所有shell中都有效,但在Bash中有效。
Ole Tange 2014年

我可以tar使用添加到问题中的简单示例来确认首先读取文件列表。但是,再次阅读tar的源代码,在我看来,如果不创建增量存档,它应该“即时”读取文件列表。不幸的是,我tar从源代码编译时
遇到了

我还没有找到一种方法来抑制输出的最后一行cpio,比其他grep -v 'blocks$'。(head -n -1使用非常大的缓冲区...)使此解决方案有点
破烂

@krlmlr很奇怪:head -n -1当运行数GB的数据时,我仅使用16MB。您可以随时使用perl的过程:perl -ne '打印$最后; $最后= $ _'
奥莱丹

7

RTFM的经典案例(全部!)-TGNU 的选项tar将从另一个文件中读取要归档的文件(在我的情况下/dev/stdin,您也可以使用-),甚至还有一个--remove-files选项:

alias magic_otf_compressor='tar --create -T - --remove-files -O | pixz'

(使用并行版本的xz进行压缩,但您可以改用首选的压缩器)。用作:

arg_generating_process |
  parallel --gnu my_process |
  magic_otf_compressor > file.tar.xz

编辑:正如Ole所指出的,出于某种原因,tar似乎使用该-T选项读取了整个文件列表。以下测试证实了这一点:

for ((f = 0; $f < 1000; f++)); do
    touch $f; echo $f;
done | tar -c -f otf.tar -T - -v

在一次打印所有文件之前,我的系统延迟了一秒钟;相反,如果将tar命令替换为cat,则在创建文件时将打印所有文件。让我们来看看,我已经向tar人提出了支持请求

EDIT ^ 2:最新tar的源代码可以解决此问题。它尚未在Ubuntu 13.10中提供,但可能包含在14.04中。


1

对于固态压缩器(基于磁带的存档器+压缩),这似乎不怎么好。一个接一个地插入文件看起来像是一项工作zip或某种其他格式,它允许在存档中进行随机文件访问并进行增量插入。

文件相似的事实在两种情况下都无济于事。在中zip,文件是单独压缩的,而在固态压缩器中,通常会在其中进行压缩的窗口中。

如果文件是基于文本的,则可以存储与单个参考文件相比的差异。对于二进制文件,这比较棘手,但是可以完成。

还有一种正式的方式(不是只写,而是适当的文件系统)。例如,ZFS和BTRFS文件系统提供透明的压缩。您也可以使用此http://developer.berlios.de/projects/fusecompress


我的文件每个大约10万。压缩器使用1M的窗口还不够吗?xz似乎使用8M的默认字典大小运行(在默认压缩级别-6),这对于我的用例来说似乎足够了。-与参考文件的区别很好,但需要先构造参考文件。压缩文件系统会检测到内容几乎相同的文件吗?
krlmlr 2014年

压缩文件系统不会跨文件压缩(zip也不会压缩),但btrfs确实具有写时复制功能,因此,如果复制文件并修改文件的一部分,则仅保存您更改的部分。如果您不是以这种方式创建文件,则可能存在重复数据删除工具,但btrfs它不是一个成熟且稳定的文件系统,因此重复数据删除处于开发的早期阶段。但是现在我想到了,lessfs.com/wordpress
Orion

对于我的用例,我的确使用固体压缩器获得了令人印象深刻的压缩率,但是,正如您概述的那样,我认为如果文件大于字典大小,结果会更糟。
krlmlr 2014年

0

它可能看起来并不明显,但是我敢打赌,squashfs这很完美-它甚至在内核中实现。由于版本4.1 squashfs可以按命令行或通过shell脚本处理伪文件mksquash,因此mksquashfs将在创建存档时生成这些文件。

它可以处理管道 -例如,您可以将另一个进程捕获stdout到一个可安装的squash存档中-甚至是fifos-这非常酷。在你的情况,如果你能找出它通过管道的过程中产出的脚本物流,你可以完全包住你的进程mksquashfs,并用一个单一的存档拉闸。这里有一些readme工作原理,还有更多内容

Mksquashfs 4.1添加了对“动态伪文件”的支持和修改操作。动态伪文件允许在运行Mksquashfs时动态创建文件,其内容是运行命令或Shell脚本的结果。修改操作允许修改源文件系统中现有文件的模式/ uid / gid。

创建动态文件示例

创建一个文件“ dmesg”,其中包含dmesg的输出。

    dmesg f 444 root root dmesg

创建一个文件RELEASE,其中包含发行版名称,日期,构建主机和递增的版本号。递增版本是执行Shell脚本的副作用,并确保每次运行Mksquashfs时都使用新版本号,而无需任何其他Shell脚本。

    RELEASE f 444 root root \
        if [ ! -e /tmp/ver ]; then \
        echo 0 > /tmp/ver; \
        fi; \
        ver=`cat /tmp/ver`; \
            ver=$((ver +1)); \
            echo $ver > /tmp/ver; \
            echo -n "release x.x"; \
            echo "-dev #"$ver `date` "Build host" `hostname`

从设备/ dev / sda1复制10K到文件输入中。通常,给定设备,fifo或命名套接字的Mksquashfs会将特殊文件放置在Squashfs文件系统中,这允许捕获来自这些特殊文件的输入并将其放置在Squashfs文件系统中。

        input f 444 root root dd if=/dev/sda1 bs=1024 count=10

在我概述的基础架构中,这将如何工作?
krlmlr 2014年

您将必须让进程将其文件名写入mksquash的调用脚本,并让其在运行时继续追加文件名。甚至连成一个tmpfs,壁球都将在运行时读取并压缩。或者,正如另一个提到的那样,通过其他方式-像上面的dd示例一样调用cpio,但是使用cpio时,可以使用其复制功能。无论如何-它绝对可以即时读取,创建和压缩。
mikeserv 2014年

会跨文件压缩吗?
krlmlr 2014年

它将输入压缩为流-所有inode,全部。我将它与dd一起使用,这非常酷-我始终使用1MB的块大小和xz压缩。
mikeserv 2014年

这看起来像一个选项,但是从您的答案中,我看不到如何创建一个带有该目录中的目录test和文件的squashfs存档file。您能否提供一个简短的例子?
krlmlr 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.