java—压缩在hadoop中的工作原理

slwdgvem  于 2021-06-04  发布在  Hadoop
关注(0)|答案(2)|浏览(324)

在我的mr工作中,比如说,我为map或reduce输出指定压缩,它是如何被压缩的?map或REDUCT任务中的全部数据是首先不经过压缩而获得,然后在最后,未压缩的数据被压缩,还是增量压缩并写入。如果它被增量压缩和写入,那么它是如何完成的?请帮我理解这个。
谢谢,
文卡特

llmtgqce

llmtgqce1#

我想我应该在tariq的答案中添加更多的细节,解释一下在更高的层次上压缩在mapreduce管道中的位置。希望这是有帮助的。
如果为Map阶段指定压缩( mapreduce.map.output.compress=true )中间Map输出数据将使用您指定的任何编解码器进行压缩( mapreduce.map.ouput.compress.codec=org.apache.hadoop.io.compress.* )并在每个Map任务完成时保存到磁盘(如果Map任务超过序列化缓冲区限制,并开始溢出到磁盘,则更早)。然后在mapreduce作业的shuffle&sort阶段,从磁盘读取压缩数据并发送到相应的节点。
在这个阶段(Map输出),压缩结果在可拆分方面没有任何好处,因此gzip或snappy编解码器以及lzo和bzip2都值得尝试。gzip通常对大多数数据具有更好的压缩比,但会严重消耗cpu,而snappy则更快,压缩比更低(即,它的延迟更少,或者不会像gzip那样严重消耗cpu…我不确定原因)。使用teragen生成的数据,gzip与snappy的压缩比分别为3.5倍和2.5倍。显然,您的数据和硬件限制将决定在您的情况下什么是最有益的编解码器。
在shuffle&sort阶段之前进行压缩是很有帮助的,因为它减少了磁盘io,并且减少了网络带宽,因为您通过有线传输压缩的数据。我想不出一个好的理由在这个阶段不压缩数据,只要这样做的cpu资源没有被争夺。在我的小10节点hadoop集群中,运行在1 gb网络上,只在map输出阶段打开压缩(即在shuffle&sort阶段压缩之前的中间map数据;最终输出未压缩)与不使用压缩相比,100gbterasort作业的总作业时间分别提高了41%(gzip)和45%(snappy)。这些实验中的数据是使用teragen生成的。当然,您的结果会因数据集、硬件和网络而异。
压缩后的数据在reduce阶段开始时被解压。
压缩在最终输出(mapreduce.output.fileoutputformat.compress=true)的reduce阶段结束时再次起作用。如果您要将输出输入到另一个mapreduce作业中,那么可拆分lzo或bzip2压缩可能在这里很有用。如果您不在输出上使用可拆分的压缩编解码器并对该数据运行作业,那么只能使用单个Map器,这将破坏hadoop的主要优点之一;并行化。解决这个问题的一种方法是使用gzip编解码器,为输出创建一个序列文件。序列文件是可拆分的,因为它本质上是附加在一起的一系列压缩文件。序列文件在每个文件附加到另一个文件的边界处是可拆分的。

6fe3ivhb

6fe3ivhb2#

它基本上取决于您使用的文件类型。如果它是一个文本文件,那么压缩发生在文件级。但如果是sequencefile,则压缩可以是在记录级别或块级别。注意,这里的块表示使用序列文件的缓冲区,而不是hdfs块。
如果是块压缩,那么多个记录一次压缩成一个块。将记录添加到块中,直到它达到以字节为单位的最小大小。通过从缓冲区大小中减去压缩算法的最大开销来计算一次要压缩的输入数据的最大大小。zlib算法的默认缓冲区大小为512字节,压缩开销为18字节(缓冲区大小的1%加12字节)。然后用给定的输出流和压缩器创建一个blockcompressorstream,并写入压缩数据。
希望这能在一定程度上回答这个问题。

相关问题