Hadoop数据组织与压缩优化指南
立即解锁
发布时间: 2025-08-25 00:55:07 阅读量: 1 订阅数: 6 

# Hadoop数据组织与压缩优化指南
## 1. 小文件处理
在Hadoop中直接处理小文件会导致NameNode内存占用过高,MapReduce作业运行缓慢。可采用以下几种方法来缓解这些问题:
- **生成多个zip文件**:尽量使zip文件大小接近HDFS块大小。
- **使用CombineFileInputFormat**:将多个输入分片(跨多个文件)输入到单个map任务中,减少所需的map任务数量。
- **创建tarball文件**:将所有文件打包成一个tarball文件,并创建一个单独的文本文件,包含tarball文件在HDFS中的位置。但这种方法会绕过MapReduce的本地化特性,可能导致不必要的网络I/O。
- **使用Hadoop Archive文件(HARs)**:这是专门为解决小文件问题而创建的Hadoop文件,是位于HDFS之上的虚拟文件系统。不过,HAR文件无法针对MapReduce中的本地磁盘访问进行优化,也不能进行压缩。
- **使用HDFS Federation**:HDFS被划分为多个不同的命名空间,每个命名空间由单独的NameNode独立管理。这样可以将内存中保存块信息的总体影响分散到多个NameNode上,从而支持更多的小文件。
- **使用MapR分布式文件系统**:MapR提供的Hadoop发行版有自己的分布式文件系统,支持大量小文件。但迁移到MapR会对系统造成较大改变。
这里推荐使用Avro来存储多个小二进制文件,因为它支持可分割文件和压缩,并且具有表达性强的模式语言,有助于版本控制。
## 2. 原子数据移动
在Hadoop中,诸如分区和压缩等操作通常会先在暂存目录中生成输出文件,然后在所有输出文件成功暂存后,需要将它们原子性地移动到最终目标位置。这会带来以下几个问题:
- **触发原子移动的条件**:如何确定何时准备好执行原子移动?
- **在HDFS中原子移动数据的方法**:如何在HDFS中原子地移动数据?
- **数据移动对最终数据读取者的影响**:数据移动会对最终数据的读取者产生什么影响?
不建议在MapReduce驱动程序中作为后处理步骤执行原子移动,因为如果客户端进程在MapReduce应用程序完成之前死亡,可能会导致问题。使用Hadoop中的OutputCommitter可以将任何原子文件移动作为作业的一部分来执行。
在HDFS中原子移动数据,曾经认为DistributedFileSystem类的rename方法是原子操作,但实际上并非如此。虽然HADOOP - 6240修复了这个问题,但出于向后兼容性的原因,rename方法并未更新。因此,需要使用新的API:
```java
DistributedFileSystem fs = (DistributedFileSystem) FileSystem.get(new Configuration());
fs.rename(src, dest, Options.Rename.NONE);
```
HDFS目前缺少原子交换目录的功能,不过有一个开放的JIRA票“Atomic Directory Swapping Operation”,有望在未来提供此功能。
## 3. 压缩编解码器选择
### 3.1 压缩编解码器概述
Hadoop中可用的压缩编解码器如下表所示:
| 编解码器 | 背景 |
| --- | --- |
| Deflate | 类似于zlib,与gzip使用相同的压缩算法,但没有gzip头。 |
| gzip | 文件格式由头和主体组成,主体包含Deflate压缩的有效负载。 |
| bzip2 | 一种节省空间的压缩编解码器。 |
| LZO | 基于块的压缩算法,允许分割压缩数据。 |
| LZOP | LZO加上额外的头。曾经LZO/LZOP与Hadoop捆绑在一起,但由于GPL许可限制已被移除。 |
| LZ4 | 基于LZO相同压缩算法的快速衍生版本。 |
| Snappy | Google的开源压缩算法,用于MapReduce和BigTable中的数据压缩。主要缺点是不可分割。 |
### 3.2 评估标准
选择压缩编解码器时,可基于以下功能和性能特征的评估标准:
- **空间/时间权衡**:通常,计算成本较高的压缩编解码器会产生更好的压缩比,从而使压缩输出更小。
- **可分割性**:压缩文件能否被分割以供多个mapper使用?如果不能分割,只有单个mapper可以处理该文件,可能会导致数据本地化丢失和网络I/O开销。
- **本地压缩支持**:是否有执行压缩和解压缩的本地库?本地库通常比没有底层本地库支持的Java编写的压缩编解码器性能更好。
### 3.3 编解码器比较
| 编解码器 | 扩展名 | 许可 | 可分割 | 仅Java压缩支持 | 本地压缩支持 |
| --- | --- | --- | --- | --- | --- |
| Deflate | .deflate | zlib | 否 | 是 | 是 |
| gzip | .gz | GNU GPL | 否 | 是 | 是 |
| bzip2 | .bz2 | BSD | 是(Java版本在Hadoop 2和1.1.0及以后版本可分割,本地版本目前不可分割) | 是 | 是 |
| LZO | .lzo_deflate | GNU GPL | 否 | 否 | 是 |
| LZOP | .lzo | GNU GPL | 是(需要预处理创建索引文件) | 否 |
0
0
复制全文
相关推荐










