在 Hadoop 上下文中,压缩编解码器的可拆分性是什么意思?

Ank*_*try 2 compression hadoop hdfs

当我遇到一个术语“可拆分”时,我正在学习各种压缩编解码器。现在这个术语在我研究过的任何互联网资源和书籍中都没有得到太多解释,所以我想我可能在这里遗漏了一些微不足道的东西。我的第一个猜测是,某些编解码器将元数据作为标头/拖尾添加到压缩文件中,这意味着如果将压缩文件拆分为多个 HDFS 块进行存储,则除非所有拆分都是合并在一起。如果是这种情况,不可拆分文件的拆分(块)如何发送到映射器以输入到 MR 应用程序?

我知道 hadoop 确实支持 gzip(不可拆分编解码器),但我不明白具体是如何支持的。

有人可以详细解释编解码器不可拆分的含义是什么或共享一些具有相同作用的链接吗?

K S*_*hin 6

摘自 Tom White 撰写的“Hadoop The Definitive Guide”,关于 Hadoop I/O、压缩和输入拆分的章节:

假设我们在 HDFS 中有一个 1 GB 大小的文件,其块大小为 64 MB。这意味着文件存储在 16 个块中。使用此文件作为输入的 MapReduce 作业将创建 16 个输入拆分,每个拆分作为单独映射任务的输入独立处理。

现在想象一下,该文件是一个 gzip 压缩文件,其压缩大小为 1 GB。和以前一样,HDFS 将文件存储为 16 个块。但是,为每个块创建拆分是行不通的,因为不可能在 gzip 流中的任意点开始读取,因此地图任务不可能独立于其他块读取其拆分。gzip 格式使用 DEFLATE 存储压缩数据,DEFLATE 将数据存储为一系列压缩块。问题是每个块的开始都没有以任何方式区分,这将允许位于流中任意点的读取器前进到下一个块的开头,从而与流同步。因此,gzip 不支持拆分。

在这种情况下,MapReduce 会做正确的事情并且不会尝试拆分 gzip 压缩的文件,因为它知道输入是 gzip 压缩的(通过查看文件扩展名)并且 gzip 不支持拆分。这会起作用,但以牺牲局部性为代价:单个映射将处理 16 个 HDFS 块,其中大部分对映射来说不是本地的。此外,地图越少,作业的粒度就越小,因此运行时间可能会更长。

如果我们假设的例子中的文件是 LZO 文件,我们会遇到同样的问题,因为底层压缩格式没有为读取器提供与流同步的方法。但是,可以使用 Hadoop LZO 库附带的索引器工具预处理 LZO 文件。该工具构建了分割点的索引,当使用适当的 MapReduce 输入格式时,有效地使它们可分割。

另一方面,bzip2 文件确实提供了块之间的同步标记(pi 的 48 位近似值),因此它确实支持拆分。

Compression format| Algorithm | Splittable
-------------------------------------------------------------------
gzip              | DEFLATE   | No
bzip2             | bzip2     | Yes
LZO               | LZO       | Yes 
Snappy            | Snappy    | No
Run Code Online (Sandbox Code Playgroud)

请参阅关于压缩和分裂的详细信息

  • 看起来几乎所有这些都是直接引用一本书。请看一下:[如何引用别人写的材料](http://stackoverflow.com/help/referencing)。除了将他人的工作归功于自己之外,它还剥夺了读者了解更多细节的机会。 (2认同)