在hadoop的上下文中,压缩编解码器的可拆分性意味着什么?

yjghlzjz  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(420)

我在学习各种压缩编解码器时遇到了一个术语“splittable”。现在这个术语在我所查阅的任何网络资源和书籍中都没有得到太多的解释,所以我想我可能遗漏了一些琐碎的东西。我的第一个猜测是,某些编解码器将元数据作为头/尾添加到压缩文件中,这意味着,如果将压缩文件拆分为多个hdfs块进行存储,除非将其所有拆分合并在一起,否则就没有任何用处。如果是这种情况,如何将不可拆分文件的拆分(块)发送到Map器以输入mr应用程序?
我知道hadoop确实支持gzip(non-splittable codec),但我不知道具体是如何实现的。
有人能详细解释一下编解码器的不可拆分性意味着什么,或者共享一些相同的链接吗?

yvgpqqbh

yvgpqqbh1#

摘自tom white的“hadoop最终指南”,关于hadoop i/o、压缩和输入拆分的章节:
假设在hdfs中有一个大小为1gb的文件,其块大小为64mb。这意味着文件存储在16个块中。使用此文件作为输入的mapreduce作业将创建16个输入分割,每个分割作为单独Map任务的输入进行独立处理。
想象一下,现在这个文件是一个gzip压缩文件,其压缩大小是1gb。和以前一样,hdfs将文件存储为16个块。但是,为每个块创建一个分割将不起作用,因为不可能在gzip流中的任意点开始读取,因此map任务不可能独立于其他块读取其分割。gzip格式使用deflate存储压缩数据,deflate将数据存储为一系列压缩块。问题是,没有以任何方式区分每个块的开头,这将允许位于流中任意点的读取器前进到下一个块的开头,从而使其自身与流同步。因此,gzip不支持拆分。
在这种情况下,mapreduce会做正确的事情,不会尝试分割gzip文件,因为它知道输入是gzip压缩的(通过查看文件扩展名),并且gzip不支持分割。这将起作用,但以牺牲位置为代价:单个Map将处理16个hdfs块,其中大多数块不是Map的本地块。此外,使用更少的Map,作业的粒度更小,因此可能需要更长的时间才能运行。
如果我们假设的示例中的文件是lzo文件,那么我们也会遇到同样的问题,因为底层压缩格式不提供读取器与流同步的方法。但是,可以使用hadoop lzo库附带的索引器工具预处理lzo文件。该工具构建分割点的索引,当使用适当的mapreduce输入格式时,有效地使其可分割。
另一方面,bzip2文件确实提供了块之间的同步标记(pi的48位近似值),因此它确实支持拆分。

Compression format| Algorithm | Splittable
-------------------------------------------------------------------
gzip              | DEFLATE   | No
bzip2             | bzip2     | Yes
LZO               | LZO       | Yes 
Snappy            | Snappy    | No

有关压缩和拆分的更多详细信息,请参阅本文

相关问题