Hadoop 3.x 默认输入格式与自定义输入格式详解
一、默认输入格式:TextInputFormat
Hadoop 3.x 延续了 TextInputFormat 作为默认输入格式,专为处理文本数据设计,适用于日志文件、CSV 等场景。
核心特性
-
记录划分规则
- 按行分割文本文件,每行为一条记录。
- Key 类型为
LongWritable(表示行起始字节偏移量)。 - Value 类型为
Text(存储行内容)。
-
分片策略
- 基于 HDFS 块大小(默认 128MB)生成
InputSplit。 - 自动处理跨块的完整行:若某行跨越两个块,分片会从下一块的起始位置开始读取,确保数据完整性。
- 基于 HDFS 块大小(默认 128MB)生成
-
压缩支持
- 支持 Gzip、Bzip2 等压缩格式,但需注意:
- 可切分压缩:Bzip2 允许分片并行处理。
- 不可切分压缩:Gzip 文件必须整体处理,无法并行。
- 支持 Gzip、Bzip2 等压缩格式,但需注意:
配置方式
job.setInputFormatClass(TextInputFormat.class); // 显式声明(默认无需配置)
二、自定义输入格式
当处理非文本数据(如二进制、JSON、数据库记录)时,需通过自定义 InputFormat 实现高效解析。
实现步骤
-
定义 InputFormat 类
继承FileInputFormat<KeyType, ValueType>,重写关键方法:public class CustomInputFormat extends FileInputFormat<MyKey, MyValue> { @Override public RecordReader<MyKey, MyValue> createRecordReader(InputSplit split, TaskAttemptContext context) { return new CustomRecordReader(); } @Override protected boolean isSplitable(JobContext context, Path file) { // 控制文件是否可分片(如针对特定压缩格式返回 false) return true; } } -
实现 RecordReader
核心类,负责实际数据解析逻辑:public class CustomRecordReader extends RecordReader<MyKey, MyValue> { private LineRecordReader lineReader; // 可复用组件 private MyKey currentKey; private MyValue currentValue; @Override public void initialize(InputSplit split, TaskAttemptContext context) { lineReader = new LineRecordReader(); lineReader.initialize(split, context); } @Override public boolean nextKeyValue() throws IOException { if (!lineReader.nextKeyValue()) return false; // 解析 lineReader.getCurrentValue() 到 currentKey/currentValue return true; } @Override public MyKey getCurrentKey() { return currentKey; } @Override public MyValue getCurrentValue() { return currentValue; } // 其他方法(getProgress(), close())... } -
注册与使用
job.setInputFormatClass(CustomInputFormat.class);
Hadoop 3.x 优化点
- Reusable Writable 对象:通过对象复用减少 GC 压力,适合高频调用的
RecordReader。 - 增强的分片策略:支持更细粒度的分片控制(如 ORC/Parquet 文件的列裁剪分片)。
三、典型场景对比
| 场景 | 默认输入格式 (TextInputFormat) | 自定义输入格式 |
|---|---|---|
| 数据类型 | 纯文本(日志、CSV) | 二进制、结构化数据(Protobuf、JSON) |
| 分片灵活性 | 基于行边界自动处理 | 可自定义分片逻辑(如按数据块划分) |
| 性能优化 | 适合简单文本,无额外解析开销 | 可针对特定格式优化反序列化性能 |
| 开发成本 | 零配置,开箱即用 | 需实现 InputFormat + RecordReader |
四、实践建议
-
优先使用内置格式
- 对 SequenceFile 使用
SequenceFileInputFormat。 - 对 Avro 数据使用
AvroKeyInputFormat。
- 对 SequenceFile 使用
-
分片策略优化
- 若数据存储格式包含元数据(如 Parquet Footer),需在
isSplitable()中避免错误分片。
- 若数据存储格式包含元数据(如 Parquet Footer),需在
-
兼容性处理
- Hadoop 3.x 的
YARN Timeline Service v2对大规模任务元数据管理更高效,可提升自定义格式作业的稳定性。
- Hadoop 3.x 的
总结
Hadoop 3.x 默认的 TextInputFormat 为文本处理提供高效基础支持,而自定义输入格式通过灵活扩展满足复杂数据类型的处理需求。开发者需权衡开发成本与性能收益,结合内置格式(如 Avro/SequenceFile)与新特性(如可重用序列化)构建最优方案。
4352

被折叠的 条评论
为什么被折叠?



