Hadoop MR:最好有压缩的输入文件或原始文件



从这个问题中可以得出,我想知道什么时候有压缩格式的输入文件(如gzip)有意义,什么时候有未压缩格式的输出文件有意义。

压缩文件的开销是多少?读取文件时速度慢得多吗?是否对大型输入文件进行了基准测试?

Thx!

除非你正在进行开发,并且你需要经常从HDFS读取数据到本地文件系统来处理它,否则使用压缩格式的输入文件是有意义的。

压缩格式提供了显著的优势。数据已经在Hadoop集群中复制,除非您以其他方式进行设置。复制的数据具有良好的冗余性,但会占用更多的空间。如果您的所有数据都是以3的倍数复制的,那么您将消耗存储数据所需容量的3倍

对像日志数据这样的文本数据进行压缩是非常有效的,因为它产生了高压缩比。这也是您通常在Hadoop集群中更常见的数据类型。

我没有基准,但我没有看到对我们拥有的一个相当大的集群和数据有任何重大的惩罚。

无论如何,暂时选择LZO而不是gzip。

参见:LZO压缩及其在gzip 上的意义

Gzip比LZO压缩得更好。LZO在压缩和解压缩方面更快。可以拆分Lzo文件,splittable Gzip不可用,但我见过Jira的任务。(也适用于bzip2)

让我们把压缩的原因和不压缩的原因放在一起。

用于:

a) 数据大多是存储的,不经常处理。这是通常的DWH场景。在这种情况下,空间节省可能比处理开销大得多
b)压缩因子非常高,因此我们节省了大量IO。
c)解压缩非常快(如Snappy),因此我们可以用很少的价格获得一些收益
d)数据已到达压缩

反对:

a) 压缩数据不可拆分。必须注意的是,许多现代格式都是用块级压缩构建的,以实现文件的拆分和其他部分处理。b) 数据是在集群中创建的,压缩需要相当长的时间。需要注意的是,压缩通常比解压缩占用更多的CPU
c)数据几乎没有冗余,压缩带来的收益也很小

1)压缩输入文件如果输入文件被压缩,那么从HDFS读取的字节就会减少,这意味着读取数据的时间会减少。这种时间节约有利于作业执行的性能。

如果输入文件被压缩,MapReduce读取时会自动解压缩,使用文件扩展名来确定要使用的编解码器。例如,以.gz结尾的文件可以被识别为gzip压缩文件,因此可以使用GzipCodec读取。

2) 压缩输出文件通常我们需要将输出存储为历史文件。如果每天的输出量很大,并且我们经常需要存储历史结果以备将来使用,那么这些累积的结果将占用大量的HDFS空间。然而,这些历史文件可能不会经常使用,从而浪费HDFS空间。因此,在HDFS上存储之前,有必要压缩输出。

3) 压缩地图输出即使MapReduce应用程序读取和写入未压缩的数据,它也可能从压缩映射阶段的中间输出中受益。由于映射输出被写入磁盘并通过网络传输到reducer节点,因此通过使用LZO或Snappy等快速压缩器,您可以获得性能提升,因为要传输的数据量减少了。2.通用输入格式

gzip:gzip自然受到Hadoop的支持。gzip基于DEFLATE算法,该算法是LZ77和霍夫曼编码的结合。

bzip2:bzip2是一款免费提供、无专利(见下文)、高质量的数据压缩器。它通常将文件压缩到最佳可用技术(PPM系列统计压缩器)的10%到15%以内,同时压缩速度大约是压缩速度的两倍,解压缩速度大约是解压缩速度的六倍。

LZO:LZO压缩格式由许多较小(~256K)的压缩数据块组成,允许沿块边界分割作业。此外,它的设计考虑到了速度:它的解压缩速度大约是gzip的两倍,这意味着它足够快,可以跟上硬盘的读取速度。它的压缩效果不如gzip——除了文件比其gzip版本大50%的数量级之外。但在没有任何压缩的情况下,这仍然是文件大小的20-50%,这意味着IO绑定作业完成映射阶段的速度大约快四倍。

Snappy:Snappy是一个压缩/解压缩库。它不以最大压缩为目标,也不与任何其他压缩库兼容;相反,它的目标是非常高的速度和合理的压缩。例如,与zlib的最快模式相比,Snappy对大多数输入的速度要快一个数量级,但产生的压缩文件要大20%到100%。在64位模式下的酷睿i7处理器的单核上,Snappy以约250 MB/秒或更高的速度压缩,以约500 MB/秒甚至更高的速率解压缩。Snappy在谷歌内部广泛使用,从BigTable和MapReduce到我们的内部RPC系统,无所不包。

一些权衡:所有压缩算法都表现出空间/时间的权衡:更快的压缩和解压缩速度通常以较小的空间节省为代价。上表中列出的工具通常通过提供九种不同的选项来控制压缩时的这种权衡:-1表示优化速度,-9表示优化空间。

不同的工具具有非常不同的压缩特性。Gzip是一种通用的压缩器,处于空间/时间权衡的中间位置。Bzip2比gzip压缩更有效,但速度较慢。Bzip2的解压缩速度比压缩速度快,但仍然比其他格式慢。另一方面,LZO和Snappy都优化了速度,比gzip快一个数量级,但压缩效果较差。Snappy在解压缩方面也明显快于LZO。3.关于压缩和输入分割的问题在考虑如何压缩将由MapReduce处理的数据时,了解压缩格式是否支持拆分是很重要的。考虑一个存储在HDFS中的未压缩文件,其大小为1GB。HDFS块大小为64MB时,文件将存储为16个块,使用此文件作为输入的MapReduce作业将创建16个输入拆分,每个拆分都作为单独地图任务的输入进行独立处理。

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

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

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

另一方面,bzip2文件确实提供了块之间的同步标记(π的48位近似值),因此它确实支持拆分。4.IO绑定和CPU绑定将压缩数据存储在HDFS中可以进一步分配硬件,因为压缩数据通常是原始数据大小的25%。此外,由于MapReduce作业几乎总是与IO绑定,存储压缩数据意味着要做的总体IO更少,这意味着作业运行得更快。然而,有两个注意事项:一些压缩格式无法拆分以进行并行处理,而另一些压缩格式的解压缩速度足够慢,以至于作业被CPU限制,从而消除了您在IO上的收益。

gzip压缩格式说明了第一个警告。假设您有一个1.1 GB的gzip文件,而集群的块大小为128 MB。此文件将被拆分为9个块,大小约为128MB。为了在MapReduce作业中并行处理这些块,不同的映射器将负责每个块。但这意味着第二个映射器将从文件中大约128MB的任意字节开始。gzip用于解压缩输入的contextful字典此时将为空,这意味着gzip解压缩器将无法正确解释字节。结果是Hadoop中的大型gzip文件需要由单个映射器处理,这违背了并行性的目的。

Bzip2压缩格式说明了第二个注意事项,在该注意事项中,作业会受到CPU限制。Bzip2文件压缩良好,甚至可以拆分,但解压缩算法很慢,无法跟上Hadoop作业中常见的流式磁盘读取。虽然Bzip2压缩有一些好处,因为它节省了存储空间,但运行中的作业现在会把时间花在等待CPU完成数据解压缩上,这会减慢它们的速度并抵消其他收益。5.总结压缩的原因:a) 数据大多是存储的,不经常处理。这是通常的DWH场景。在这种情况下,节省空间可能比处理开销更重要b) 压缩因子非常高,因此我们节省了大量IO。c) 解压缩非常快(像Snappy一样),因此我们可以用很少的价格获得一些收益d) 数据已到达压缩

不压缩的原因a) 压缩数据不可拆分。必须注意的是,许多现代格式都是用块级压缩构建的,以实现文件的拆分和其他部分处理。b) 数据是在集群中创建的,压缩需要相当长的时间。需要注意的是,压缩通常比解压缩占用更多的CPU。c) 数据几乎没有冗余,压缩带来的收益也很小。

相关内容

最新更新