将JSON转换为Parquet

时间:2015-10-09 00:56:46

标签: avro parquet

我有一些JSON格式的TB日志数据,我想将它们转换为Parquet格式,以便在分析阶段获得更好的性能。

我设法通过编写使用parquet-mrparquet-avro的mapreduce java作业来实现这一目标。

我唯一不满意的是,我的JSON日志没有固定的架构,我不知道所有字段的名称和类型。此外,即使我知道所有字段的名称和类型,我的模式随着时间的推移而演变,例如,将来会添加新字段。

现在我必须为AvroWriteSupport提供Avro架构,而avro只允许固定数量的字段。

有没有更好的方法在Parquet中存储任意字段,就像JSON一样?

2 个答案:

答案 0 :(得分:3)

有一点可以肯定的是,Parquet需要提前使用Avro架构。我们将专注于如何获得架构。

  1. 使用SparkSQL将JSON文件转换为Parquet文件。

    SparkSQL可以根据数据自动推断架构,因此我们不需要自己提供架构。每次数据发生变化时,SparkSQL都会推断出不同的模式。

  2. 手动维护Avro架构。

    如果您不使用Spark但只使用Hadoop,则需要手动推断架构。首先编写mapreduce作业来扫描所有JSON文件并获取所有字段,在您知道可以编写Avro架构的所有字段之后。使用此架构将JSON文件转换为Parquet文件。

    将来会有新的未知字段,每次有新字段时,都会将它们添加到Avro架构中。所以基本上我们手动做SparkSQL的工作。

答案 1 :(得分:1)

使用Apache Drill!

来自https://drill.apache.org/docs/parquet-format/,在一行SQL中。

设置Apache Drill(带或不带HDFS)后,执行sqline.sh以运行SQL查询:

// Set default format ALTER SESSION SET `store.format` = 'parquet'; 
ALTER SYSTEM SET `store.format` = 'parquet';

// Migrate data
CREATE TABLE dfs.tmp.sampleparquet AS  (SELECT trans_id,  cast(`date` AS date) transdate,  cast(`time` AS time) transtime,  cast(amount AS double) amountm, user_info, marketing_info, trans_info  FROM dfs.`/Users/drilluser/sample.json`);

应该花几个小时,也许几个小时,但最后,你有轻薄的木地板文件; - )

在我的测试中,查询镶木地板文件比JSON快x4并且请求更少的资源。