我有一个相当大的镶木地板文件,我需要更改其中一列的值。一种方法是更新源文本文件中的这些值并重新创建镶木地板文件,但我想知道是否有更便宜且整体更简单的解决方案。
4 回答
让我们从基础开始:
Parquet 是一种需要保存在文件系统中的文件格式。
关键问题:
- 拼花地板是否支持
append
运营? - 文件系统(即 HDFS)是否允许
append
文件? - 作业框架(Spark)可以实现
append
操作吗?
答案:
parquet.hadoop.ParquetFileWriter
仅支持CREATE
和OVERWRITE
;没有append
模式。(不确定,但这可能会在其他实现中发生变化——镶木地板设计确实支持append
)HDFS 允许
append
使用该dfs.support.append
属性的文件Spark 框架不支持
append
现有的 parquet 文件,并且没有计划;看到这个 JIRA
在分布式系统中追加到现有文件不是一个好主意,特别是考虑到我们可能同时有两个写入者。
更多细节在这里:
有一些变通方法,但您需要以某种方式创建 parquet 文件以使其更易于更新。
最佳实践:
A. 使用行组创建 parquet 文件。在数据压缩和字典编码等功能停止发挥作用之前,您需要优化可以进入行组的数据行数。
B. 一次扫描一个行组并找出需要更新哪些行组。为每个修改的行组生成带有修改数据的新 parquet 文件。一次处理一个行组的数据而不是文件中的所有数据,内存效率更高。
C. 通过附加未修改的行组和通过读取每个行组的一个 parquet 文件生成的修改的行组来重建原始 parquet 文件。
使用行组重新组装 parquet 文件的速度非常快。
从理论上讲,如果您只是剥离页脚(统计信息),附加新行组并添加带有更新统计信息的新页脚,应该很容易附加到现有的镶木地板文件,但没有支持它的 API / 库。
看看这个不错的博客,它可以回答你的问题并提供一种使用 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
免责声明:我没有写过那些博客,我只是读了它,发现它可能对其他人有用。
您必须重新创建文件,这是 Hadoop 方式。特别是如果文件被压缩。
另一种方法(在大数据中非常常见)是在另一个 Parquet(或 ORC)文件上进行更新,然后在查询时进行 JOIN / UNION。