4

正如可以从问题中得出的那样,我想知道何时以压缩格式(如gzip)输入文件有意义,何时以未压缩格式输入文件有意义。

压缩文件的开销是多少?读取文件时会慢很多吗?是否对大输入文件进行了任何基准测试?

谢谢!

4

3 回答 3

6

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

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

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

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

但是,暂时选择 LZO 而不是 gzip。

请参阅:LZO 压缩及其对 gzip 的意义

Gzip 比 LZO 压缩得更好。LZO 在压缩和解压缩方面更快。可以拆分 Lzo 文件,可拆分的 Gzip 不可用,但我已经看到了相同的 Jira 任务。(也适用于 bzip2)

于 2012-06-27T15:24:56.650 回答
2

让我们把压缩的理由和不压缩的理由放在一起。

为了:

a) 数据大部分是存储的,而不是经常处理的。这是通常的 DWH 方案。在这种情况下,节省空间可能比处理开销更重要
b) 压缩因子非常高,因此我们节省了大量 IO。
c) 解压速度非常快(如 Snappy),因此我们以很小的代价获得了一些收益
d) 数据已经压缩到达

反对:

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

于 2012-06-27T18:13:24.970 回答
1

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

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

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

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

gzip:gzip 是 Hadoop 自然支持的。gzip 基于 DEFLATE 算法,是 LZ77 和 Huffman Coding 的结合。

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

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

Snappy:Snappy 是一个压缩/解压库。它的目标不是最大压缩或与任何其他压缩库的兼容性;相反,它的目标是非常高的速度和合理的压缩。例如,与 zlib 的最快模式相比,Snappy 对于大多数输入来说要快一个数量级,但生成的压缩文件要大 20% 到 100%。在 64 位模式的 Core i7 处理器的单个内核上,Snappy 以大约 250 MB/秒或更高的速度压缩,并以大约 500 MB/秒或更高的速度解压缩。Snappy 在 Google 内部被广泛使用,从 BigTable 和 MapReduce 到我们内部的 RPC 系统。

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

不同的工具具有非常不同的压缩特性。Gzip 是一种通用压缩器,位于空间/时间权衡的中间。Bzip2 比 gzip 更有效地压缩,但速度较慢。Bzip2 的解压速度比它的压缩速度快,但还是比其他格式慢。另一方面,LZO 和 Snappy 都针对速度进行了优化,并且比 gzip 快了大约一个数量级,但压缩效率较低。Snappy 的解压速度也明显快于 LZO。3. 关于压缩和输入拆分的问题 在考虑如何压缩将由 MapReduce 处理的数据时,了解压缩格式是否支持拆分很重要。考虑一个存储在 HDFS 中的未压缩文件,其大小为 1 GB。HDFS 块大小为 64 MB,

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

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

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

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

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

Bzip2 压缩格式说明了作业受 CPU 限制的第二个警告。Bzip2 文件压缩得很好,甚至可以拆分,但解压算法很慢,无法跟上 Hadoop 作业中常见的流式磁盘读取。虽然 Bzip2 压缩有一些好处,因为它节省了存储空间,但现在正在运行的作业会花费时间等待 CPU 完成数据解压缩,这会减慢它们的速度并抵消其他好处。5. 压缩的总结原因: a) 数据大部分是存储的,而不是经常处理的。这是通常的 DWH 方案。在这种情况下,节省空间可能比处理开销更重要 b) 压缩因子非常高,因此我们节省了大量 IO。

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

于 2015-09-03T17:14:46.883 回答