当我遇到一个可分割的术语时,我正在学习各种压缩编解码器。现在这个术语在我所研究的任何互联网资源和书籍中都没有得到很多解释,所以我想我可能会在这里遗漏一些微不足道的东西。我的第一个猜测是某些编解码器将元数据作为标题/预告片添加到压缩文件中,这意味着如果将一个压缩文件拆分成多个HDFS块进行存储,除非所有它都有用,否则它不会有任何用处。拆分合并在一起。如果是这种情况,如何将不可拆分文件的拆分(块)发送给映射器以输入MR应用程序?
我知道hadoop确实支持gzip(不可拆分的编解码器)这一事实,但我不知道究竟是怎么做的。
有人可以详细解释编解码器的不可拆分性的含义,或者分享一些相同的链接吗?
答案 0 :(得分:3)
摘录自" Hadoop The Definitive Guide"作者:Tom White,关于Hadoop I / O,压缩和输入拆分的章节:
假设我们在HDFS中有一个1 GB大小的文件,其块大小为64 MB。这意味着文件存储在16个块中。使用此文件作为输入的MapReduce作业将创建16个输入拆分,每个拆分独立处理为单独的地图任务的输入。
想象一下,现在该文件是一个压缩大小为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
有关压缩和拆分的详细信息,请参阅this