将JSON转换为Parquet

3
我有几个TB的JSON格式日志数据,我想将它们转换为Parquet格式以在分析阶段获得更好的性能。我通过编写一个使用parquet-mrparquet-avro的mapreduce java作业来实现这一点。
唯一让我不满意的是,我的JSON日志没有固定的模式,我不知道所有字段的名称和类型。此外,即使我知道所有字段的名称和类型,我的模式也会随着时间的推移而发展,例如,未来会添加新字段。
目前,我必须为AvroWriteSupport提供一个Avro模式,而avro仅允许固定数量的字段。是否有更好的方法来存储Parquet中的任意字段,就像JSON一样?
2个回答

4
肯定的一件事是Parquet需要提前有一个Avro模式。我们将关注如何获得这个模式。
  1. 使用SparkSQL将JSON文件转换为Parquet文件。

    SparkSQL可以自动从数据中推断出一个模式,因此我们不需要自己提供模式。每次数据更改时,SparkSQL都会推断出不同的模式。

  2. 手动维护一个Avro模式。

    如果您不使用Spark而只使用Hadoop,则需要手动推断模式。首先编写一个mapreduce作业来扫描所有JSON文件并获取所有字段,了解所有字段后,您可以编写一个Avro模式。使用此模式将JSON文件转换为Parquet文件。

    未来可能会有新的未知字段,每次有新字段时,将其添加到Avro模式中。因此,基本上我们正在手动完成SparkSQL的工作。


令人惊讶的是,我正在处理非常相似的问题。你知道第二个选项有没有任何示例吗?我只使用过Spark而没有编写过Hadoop MapReduce作业。 - Pylander
实际上,我正在生产中使用第二种方式,我的模式有超过3000个字段,这个模式是由一个MapReduce程序推断出来的,每当有新字段时,我需要再次生成模式。 - soulmachine
太好了!很高兴你发现它可行。如果您想分享任何提示或技巧,我还发布了另一个相关的问题。http://stackoverflow.com/questions/35495041/mapreduce-job-to-collect-all-unique-fields-in-hdfs-directory-of-json - Pylander

1

使用 Apache Drill!

https://drill.apache.org/docs/parquet-format/,仅使用 1 行 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`);

需要一些时间,可能几个小时,但最终你会得到轻便且酷炫的Parquet文件 ;-)
在我的测试中,查询Parquet文件比JSON快4倍,并且使用更少的资源。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接