镶木地板格式的图式演变

时间:2016-06-05 17:15:55

标签: apache-spark hadoop data-warehouse avro parquet

目前我们在生产中使用Avro数据格式。 在使用Avro的几个优点中,我们知道它在模式演化方面很有用。

现在我们正在评估 Parquet格式,因为它在阅读随机列时效率很高。 因此,在继续前进之前,我们的关注仍然是架构演变

有没有人知道在拼花地板中是否可以进行模式演变,如果是如何是可能的,如果没有则为什么不是。

有些resources声称可以,但只能在末尾添加列

这是什么意思?

2 个答案:

答案 0 :(得分:28)

架构演变可能(非常)昂贵。

为了弄清楚架构,你基本上必须阅读所有的镶木地板文件并在阅读时间内协调/合并它们的模式,这可能很昂贵,具体取决于数据集中有多少文件或/和多少列。

因此,由于 Spark 1.5 ,他们默认关闭schema merging。您可以随时重新打开它。)

  

由于模式合并是一项相对昂贵的操作,并且不是   在大多数情况下,我们必须从默认情况下将其关闭   1.5.0。

如果没有模式演变,您可以从一个镶木地板文件中读取模式,并且在阅读其余文件时假设它保持不变。

Parquet模式演变依赖于实现。

例如,Hive有一个旋钮parquet.column.index.access=false 您可以设置为按列名而不是列索引映射架构。

然后你也可以删除列,而不仅仅是添加。

正如我上面所说,它依赖于实现,例如,Impala不能正确读取这样的镶木桌(在最近的Impala 2.6版本中修复)[Reference]。

Apache Spark,从版本2.0.2开始,似乎仍然只支持添加列: [Reference]

  

用户可以从简单的架构开始,逐步添加更多列   根据需要到架构。通过这种方式,用户可能最终会有多个   具有不同但相互兼容的模式的Parquet文件。该   镶木地板数据源现在能够自动检测此案例和   合并所有这些文件的模式。

PS:我看到一些人对模式更改有了更大的敏捷性,他们在实际的镶木桌子上创建了一个视图或更多)不同但兼容的模式到一个公共模式。

我们假设您已在新版本中添加了一个新字段(registration_date)并删除了另一列(last_login_date),那么这将是:

CREATE VIEW datamart.unified_fact_vw
AS
SELECT f1..., NULL as registration_date 
FROM datamart.unified_fact_schema1 f1
UNION ALL
SELECT f2..., NULL as last_login_date
FROM datamart.unified_fact_schema2 f2
;

你明白了。好的,它可以在Hadoop方言的所有sql上工作(就像我上面提到的Hive,Impala和Spark),并且仍然具有Parquet表的所有好处(柱状存储,谓词下推等)。

答案 1 :(得分:2)

除上述答案外,其他选项是设置

"spark.hadoop.parquet.enable.summary-metadata" to "true"

这是在编写文件时使用架构创建摘要文件。保存后,您将看到文件摘要文件'_metadata''_common_metadata'_common_metadata是每次读取镶木地板文件时都会读取的压缩模式。由于您已经有了模式,因此可以非常快速地阅读。 Spark将查找这些模式文件(如果存在)以获取模式。

请注意,由于Spark必须合并所有文件的架构并创建这些架构文件,因此写入速度非常慢。

我们有类似的情况,其中实木复合地板架构发生了变化。我们所做的是在架构更改后的某个时间将上述配置设置为true,以便生成架构文件,然后将其设置回false。我们不得不妥协一些时间,但是在生成模式文件之后,将其设置为false就可以达到目的。并具有更快读取文件的好处。