随机访问gzip压缩文件?(Random access to gzipped files?)

2019-07-18 00:00发布

我用gzip坐在磁盘压缩非常大的文件。 生产环境是“云”为基础的,所以存储性能是可怕的,但CPU是好的。 以前我们的数据处理流水线开始gzip -dc流中的数据从磁盘。

现在,为了parallelise的工作,我想运行多条管线,每取一对字节偏移 - 开始和结束 - 并且采取文件的该块。 与文本文件,这可能与实现headtail ,但我不知道如何与一个压缩文件有效地做到这一点; 如果我gzip -dc和管进入head ,偏移对那些向文件的末尾将涉及浪费,通过整个文件,寻求,因为它是慢慢的解压缩。

所以我的问题实际上是关于gzip算法 - 是理论上可以寻求一个字节底层文件偏移或获取它的一个任意块,无需解压整个文件到这一点的全面影响? 如果不是,怎么回事我可能有效,同时最小化I / O吞吐量的开销分区被多个进程“随机”访问的文件?

Answer 1:

你不能这样做,用gzip,但你可以用bzip2,这是块而不是基于流的做到这一点 - 这是Hadoop的DFS是如何拆分和并行化的,在它的MapReduce算法不同映射器大文件的读取。 也许这将是有意义的重新压缩文件作为BZ2,所以你可以利用这一点; 这将是比一些特别的方式来块了文件更容易。

我发现,在Hadoop的实现这一点,这里的补丁: https://issues.apache.org/jira/browse/HADOOP-4012

下面是关于该主题的另一个帖子: Hadoop中读BZip2压缩文件

或许浏览Hadoop的源代码,会给你的如何通过块读取的bzip2文件中的想法。



Answer 2:

是的,你可以通过阅读整个事情顺序一次性和建立索引随机访问gzip文件。 见例子/ zran.c在zlib的分布。

如果你是在创建gzip文件的控制,那么你可以通过建立在随机访问的入口点优化用于此目的的文件,并建立索引,同时压缩。

您也可以通过创建一个标记gzip文件Z_SYNC_FLUSH随后Z_FULL_FLUSH在zlib的的deflate() ,以插入两个标记,使下一个块独立于以前的数据。 这将减少压缩,但不是很多,如果你不这样做太频繁。 例如,每兆字节应该具有的影响非常小。 然后,你可以搜索一个九字节标记(比bzip2的六个字节的标记可能误报少得多): 00 00 ff ff 00 00 00 ff ff



Answer 3:

gzip事实上确实希望能够从一开始就流的文件。 你不能在中间开始。

你可以做的是打破了文件到被分段与压缩块gzip ,然后连接在一起。 你可以选择你喜欢的每一件任何尺寸,例如10MB或100MB。 然后,您解压缩起始于一个包含offset您所需要的字节块的开始。 由于一个鲜为人知的特征gzip (其是解压缩的文件是几个较小gzip文件的级联产生相同的输出作为解压缩每个较小的文件,并一起串接结果)压缩大文件也将工作分段与标准gzip -d / gunzip ,如果你下载了整个事情。

最棘手的部分:你必须保持包含该字节的大文件中的每个压缩块的开始偏移的索引。



文章来源: Random access to gzipped files?