操作Parquet
Hadoop 操作 Parquet 文件:怎么读、怎么写、要注意什么
Parquet 是 Hadoop 生态里最常用的列式存储格式。跟 Text 格式相比,它的核心优势:
- 压缩率高:列式存储 + 编码压缩,文件体积比 Text 小得多
- 查询快:只读需要的列,不用整行加载(谓词下推 + 列裁剪)
- Schema 自带:文件里包含字段名、类型,读的时候不用额外定义
在 Hive、Spark、Impala 里直接用 SQL 就能查,但如果你要自己写 MapReduce 读 Parquet,就得用专门的 API。
添加依赖
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-column</artifactId>
<version>1.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-hadoop</artifactId>
<version>1.8.1</version>
</dependency>
注意: Parquet 依赖的 Guava 版本如果跟 Hadoop 的不一样,会报 NoSuchMethodError。如果遇到,参考前面问题集锦的处理方式——统一两边 Guava 版本。
读取流程三步走
读取 Parquet 文件的核心步骤是三件事:① 创建输入格式 → ② 创建记录读取器 → ③ 遍历解析每条记录。
public class ParquetReaderMapper extends Mapper<Void, Group, NullWritable, Text> {
private Gson gson = new Gson();
private Text outValue = new Text();
protected void map(Void key, Group value, Context context)
throws IOException, InterruptedException {
// 第三步:解析每条记录
outValue.set(groupToJson(value));
context.write(NullWritable.get(), outValue);
}
private String groupToJson(Group group) {
Map<String, Object> map = new HashMap<>();
// 按字段名取数,类型要匹配
map.put("name", group.getString("name", 0));
map.put("age", group.getInteger("age", 0));
return gson.toJson(map);
}
}