Parquet格式有多可重现/确定性如何?

7
我正在寻求对Apache Parquet二进制布局非常熟悉的人的建议:
在使用完全确定性的数据转换F(a) = b,以及相同版本的整个软件堆栈(框架、箭头和Parquet库)的情况下,每次将b保存到Parquet时,在不同的主机上获得dataframe b的相同二进制表示的可能性有多大?
换句话说,Parquet在二进制级别上有多可重复?当数据在逻辑上相同时,什么因素会导致二进制差异?
- 由于对齐而导致值之间存在未初始化的内存吗? - 假设所有序列化设置(压缩、分块、使用字典等)都相同,结果是否仍会漂移?
背景:
我正在开发一个系统,用于完全可重现和确定性数据处理,并计算数据集哈希以断言这些保证。
我的主要目标是确保数据集b与数据集b'包含完全相同的记录,这当然与对Arrow/Parquet的二进制表示进行哈希处理非常不同。我不想处理存储格式的可重复性,因此我一直在内存中计算逻辑数据哈希。这很慢但很灵活,例如,即使记录被重新排序(我认为这是等效的数据集),我的哈希值仍然相同。
但是,当考虑与IPFS和其他基于内容寻址的存储集成时,这些存储依赖于文件的哈希值,只有一个哈希值(物理)而不是两个(逻辑+物理)会大大简化设计,但这意味着我必须保证Parquet文件是可重现的。

更新

我决定继续使用逻辑哈希。

我创建了一个新的Rust crate arrow-digest,实现了Arrow数组和记录批处理的稳定哈希,并努力隐藏编码相关的差异。如果有人发现它有用并想在另一种语言中实现它,该crate的README描述了哈希算法。

随着我将其集成到我正在开发的分散式数据处理工具中,我将继续扩展支持的类型集。

从长远来看,我不确定逻辑哈希是否是前进的最佳方式 - Parquet的子集可能更好,它做出了一些效率上的牺牲,只是为了使文件布局确定性。


1
我对Parquet的了解还不够,无法回答这个问题。我的直觉告诉我它不是确定性的,你可能在未初始化填充方面有所发现。然而,我想指出,将相同的数据存储到parquet文件中有许多不同的方法。编写者可以选择编写统计信息或不编写统计信息,使用不同大小的行组或数据页大小,使用不同的编码方案和不同的压缩方案。所有这些都会导致相同数据的不同parquet文件。 - Pace
谢谢!填充是我最关心的问题。统计数据和其他设置都在我的控制范围内,因此如果需要,我愿意禁用所有额外功能,只要我能继续使用Parquet格式(由于其广泛支持)。 - sergey
1个回答

3
在arrow的实现中,我期望相同顺序且包含完全相同元数据的输入将产生确定性输出(出于安全原因,我们尽量避免未初始化的值),且采用相同配置(假设所选压缩算法也提供确定性保证)。可能存在元数据或其他部分的哈希映射迭代,这也可能会破坏此假设。
正如@Pace指出的那样,我不会依赖这个,并且建议不要依赖它。规范中没有任何保证,而且由于写入文件时编写版本会被持久化,如果您决定升级,则会保证破碎。如果添加或删除任何元数据,事情也会变得混乱(我相信过去已经修复了一些回转数据集的错误,否则会导致非确定性)。
因此,总之,今天可能有效,也可能无效,但即使有效,我也认为这是非常脆弱的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接