目前我们在生产中使用Avro数据格式。 在使用Avro的几个优点中,我们知道它在模式演化方面很有用。
现在我们正在评估 Parquet格式,因为它在阅读随机列时效率很高。 因此,在继续前进之前,我们的关注仍然是架构演变。
有没有人知道在拼花地板中是否可以进行模式演变,如果是如何是可能的,如果没有则为什么不是。
有些resources声称可以,但只能在末尾添加列。
这是什么意思?
答案 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
就可以达到目的。并具有更快读取文件的好处。