当前位置: 首页 > 知识库问答 >
问题:

拼花格式中的图式演变

赵开诚
2023-03-14

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

现在我们正在评估Parque格式,因为它在读取随机列时的效率。所以在前进之前,我们仍然关注模式演变。

有谁知道模式演变是否可能在镶木地板中实现,如果是,它怎么可能,如果不是,那么为什么不呢。

一些资源声称这是可能的,但它只能在末尾添加列。

这是什么意思?

共有2个答案

空成天
2023-03-14

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

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

它的作用:当您编写文件时,它会使用架构创建摘要文件。保存后,您将看到带有'_metadata''_common_metadata'后缀的摘要文件。_common_metadata是每次您读取拼花文件时都会读取的压缩架构。这使得读取速度非常快,因为您已经有了架构。Spark会查找这些架构文件(如果存在)以获取架构。

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

我们遇到了类似的情况,拼花图案发生了变化。我们所做的是在模式更改后的某个时间将上面的配置设置为< code>true,以便生成模式文件,然后将其设置回< code>false。我们不得不在一段时间内对缓慢的写入做出妥协,但是在模式文件生成之后,将其设置为< code>false就达到了目的。另外还能更快地读取文件。

田向荣
2023-03-14

模式演化可能(非常)昂贵。

为了找出模式,您基本上必须读取所有拼花文件,并在读取期间协调/合并它们的模式,这可能会很昂贵,具体取决于数据集中有多少文件或/和列。

因此,从Spark 1.5开始,他们默认关闭了模式合并。您可以随时将其重新打开)。

由于架构合并是一项相对昂贵的操作,并且在大多数情况下不是必需的,因此我们从 1.5.0 开始默认将其关闭。

如果没有架构演变,您可以从一个 Parquet 文件中读取架构,并且在读取其余文件时假定它保持不变。

拼花模式演进依赖于实现。

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

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

如上所述,它依赖于实现,例如,Impala无法正确读取此类拼花桌(在最近的Impala 2.6版本中修复)[参考]。

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

用户可以从一个简单的模式开始,然后根据需要逐渐向模式添加更多列。通过这种方式,用户可能会得到具有不同但相互兼容模式的多个拼花文件。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),并且仍然具有Parket表的所有好处(柱状存储、谓词下推等)。

页(page的缩写)补充:添加一些关于Spark可以创建的< code>common_metadata摘要文件的信息,使这个答案更加完整。

看看SPARK-15719

拼花地板摘要文件现在不是特别有用,因为

 - when schema merging is disabled, we assume 
   schema of all Parquet part-files are identical, 
   thus we can read the footer from any part-files.

- when schema merging is enabled, we need to read footers 
  of all files anyway to do the merge.

On the other hand, writing summary files can be expensive,
because footers of all part-files must be read and merged. 
This is particularly costly when appending a small dataset 
to a large existing Parquet dataset.

所以有些观点反对启用common_metadata

>

  • 当一个目录由混合了不同架构的 Parquet 文件组成时,_common_metadata允许读者为整个目录找出一个合理的架构,而无需读取每个文件的架构。由于 Hive 和 Impala 可以从 Hive 元存储访问所述文件的 SQL 架构,因此它们可以立即开始处理各个文件,并在读取时将每个文件与 SQL 架构进行匹配,而不是事先浏览其通用架构。这使得 Hive 和 Impala 不需要通用元数据功能。

    尽管Spark处理没有SQL模式的Parquet文件(除非使用SparkSQL),因此理论上可以从_common_metadata中受益,但此功能仍然被认为没有用,因此在SPARK-15719中被默认禁用。

    即使此功能对于查询很有用,但在编写过程中仍然是一个负担。必须维护元数据,这不仅速度慢,而且容易出现竞速条件和其他并发问题,缺乏原子性保证,并且容易由于过时或不一致的元数据而导致数据正确性问题。

    该功能未记录在案,似乎被视为已弃用(只有“似乎是”,因为它似乎从一开始就没有得到官方支持,并且不支持的功能也不能弃用)。

    来自Cloudera的一名工程师:“我不知道如果< code>common_metadata文件存在,读取端的行为是否发生了变化,以避免查看每个页脚。但是不管怎样,首先写那个文件是一个巨大的瓶颈,给我们的客户带来了很多问题。我强烈建议他们不要费心去生成那个元数据文件。”

    “_common_metadata”和“_metadata”文件是特定于Spark的,例如,它们不是由Impala和Hive编写的,也可能不是由其他引擎编写的。

    Spark中的摘要元数据文件可能仍有其用例-当没有上述并发性和其他问题时-例如,一些流式用例-我猜这就是为什么Spark没有完全删除此功能的原因。

  •  类似资料:
    • 我有使用Protobuf制作的主题事件。我可以使用Parquet格式的S3 sink连接器将主题事件成功地汇到S3存储桶中。现在我的S3存储桶中有和。使用以下配置,所有这些都按预期工作: 现在,我想使用Protobuf将< code > my-bucket-123 (< code > parquet 格式)的键和值放回到Kafka主题中。为此,我使用以下配置通过汇合设置了一个新的S3源连接器(<

    • 当我在snowflake中查询外部表(指向CSV文件)时,结果以JSON格式显示。 我如何检索我的结果在表格格式,而不使用任何这样的sql下面。我想做,我希望它以显示格式显示。 有什么想法吗?谢了。

    • 我正试图在模式下将写入文件格式(在最新的pandas版本0.21.0中引入)。但是,文件将被新数据覆盖,而不是附加到现有文件。我错过了什么? 写入语法是 读取语法是

    • 我们正在寻找一种解决方案,以便创建一个外部配置单元表,根据parquet/avro模式从parquet文件中读取数据。 换句话说,如何从拼花/avro模式生成hive表? 谢谢:)

    • 使用Kafka Connect HDFS Sink,我能够将avro数据写入Kafka主题并将数据保存在hive/hdfs中。 我正在尝试使用格式类以拼花文件格式保存数据 快速启动hdfs。属性如下 当我将数据发布到Kafka时,表在hive中创建,test\u hdfs\u parquet目录在hdfs中创建,但由于以下异常,Sink无法以parquet格式保存数据

    • 本文向大家介绍Kafka 消息格式的演变清楚吗?相关面试题,主要包含被问及Kafka 消息格式的演变清楚吗?时的应答技巧和注意事项,需要的朋友参考一下 用 Kafka这么久,从来都没去了解 Kafka 消息的格式。今天特意去网上搜索了以下,发现这方面的资料真少,很多资料都是官方文档的翻译;而且 Kafka消息支持压缩,对于压缩消息的格式的介绍更少。基于此,本文将以图文模式介绍 Kafka 0.7.