更新 apache parquet 文件中的值
Posted
技术标签:
【中文标题】更新 apache parquet 文件中的值【英文标题】:Updating values in apache parquet file 【发布时间】:2015-05-04 10:30:33 【问题描述】:我有一个非常大的镶木地板文件,我需要在其中更改其中一列的值。一种方法是更新源文本文件中的这些值并重新创建镶木地板文件,但我想知道是否有更便宜且整体更简单的解决方案。
【问题讨论】:
没有。您必须重新创建文件。 @DanOsipov 谢谢。我认为这种限制是由于使用了各种压缩算法,这些算法不容易甚至不可能更新列值。 我想说,这是一个更基本的问题,而不是镶木地板的具体问题。在大数据量的世界中,拼花地板被大量使用,不变性是您想要关心的事情。从这个角度来看,您希望加载数据、对其进行转换,然后再次写入。您可能会考虑只编写您需要的列,因为它是按列格式,所以效率更高。 我了解到您想要更新之前运行中已写入的字段。也许这篇文章可以提供帮助。我不是在推销任何产品。请关注所涉及的概念,而不是宣传的产品。 databricks.com/blog/2018/10/29/… 【参考方案1】:让我们从基础开始:
Parquet 是一种文件格式,需要保存在文件系统中。
关键问题:
-
parquet 是否支持
append
操作?
文件系统(即HDFS)是否允许append
处理文件?
作业框架 (Spark) 能否实现append
操作?
答案:
parquet.hadoop.ParquetFileWriter
只支持CREATE
和OVERWRITE
;没有append
模式。 (不确定,但这可能会在其他实现中发生变化——镶木地板设计确实支持append
)
HDFS 允许 append
使用 dfs.support.append
属性处理文件
Spark 框架不支持 append
到现有的 parquet 文件,并且没有计划; see this JIRA
在分布式系统中附加到现有文件不是一个好主意,尤其是考虑到我们可能同时有两个写入器。
更多细节在这里:
http://bytepadding.com/big-data/spark/read-write-parquet-files-using-spark/
http://bytepadding.com/linux/understanding-basics-of-filesystem/
【讨论】:
感谢您的详细回答和背景信息。这很有帮助【参考方案2】:有一些变通方法,但您需要以某种方式创建 parquet 文件以使其更易于更新。
最佳实践:
A.使用行组创建镶木地板文件。在数据压缩和字典编码等功能停止发挥作用之前,您需要优化可以进入行组的数据行数。
B.一次扫描一个行组并找出需要更新哪些行组。为每个修改的行组生成带有修改数据的新 parquet 文件。一次处理一个行组的数据而不是文件中的所有数据,内存效率更高。
C.通过附加未修改的行组和通过读取每个行组的一个 parquet 文件生成的修改后的行组来重建原始 parquet 文件。
使用行组重新组装 parquet 文件速度惊人。
理论上,如果您只是剥离页脚(统计信息),附加新行组并添加带有更新统计信息的新页脚,那么附加到现有 parquet 文件应该很容易,但是没有支持它的 API/库..
【讨论】:
【参考方案3】:看看这个不错的博客,它可以回答你的问题并提供一种使用 Spark(Scala) 执行更新的方法:
http://aseigneurin.github.io/2017/03/14/incrementally-loaded-parquet-files.html
从博客复制和粘贴:
当我们需要在我们的数据结构 (Parquet) 中编辑不可变的数据时。
您可以将分区添加到 Parquet 文件,但不能就地编辑数据。
但最终我们可以改变数据,我们只需要接受我们不会在原地这样做。我们需要结合使用模式和 UDF 重新创建 Parquet 文件,以纠正错误数据。
如果你想在 Parquet 中增量追加数据(你没问这个问题,对其他读者还是有用的) 参考这篇写得很好的博客:
http://aseigneurin.github.io/2017/03/14/incrementally-loaded-parquet-files.html
免责声明:我没有写过那些博客,我只是读了它,发现它可能对其他人有用。
【讨论】:
我知道这个问题比简单地附加分区更复杂一些,正如博客文章所解释的那样。假设一些数据在更多数据到达之前是有效的,这可以在 SQL 数据库上轻松实现,但需要创造性,以防您不能只更新记录的字段,这就是 parquet 文件的情况。【参考方案4】:您必须重新创建文件,这是 Hadoop 方式。特别是如果文件被压缩。
另一种方法(在大数据中非常常见)是在另一个 Parquet(或 ORC)文件上进行更新,然后在查询时进行 JOIN / UNION。
【讨论】:
以上是关于更新 apache parquet 文件中的值的主要内容,如果未能解决你的问题,请参考以下文章
雪花:因异常 java.io.IOException 失败:org.apache.parquet.io.ParquetDecodingException:无法在块 -1 中读取 0 处的值
如何在 R 中读取 Parquet 并将其转换为 R DataFrame?
java - 如何在类似于pyspark的java分区中写入parquet文件?
iceberg org.apache.iceberg.parquet.Parquet parquet file read
iceberg org.apache.iceberg.parquet.Parquet parquet file read
iceberg org.apache.iceberg.parquet.Parquet parquet file read