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

How reproducible / deterministic is Parquet format?

我正在向非常熟悉 Apache Parquet 二进制布局的人寻求建议:

进行数据转换 F(a) = b,其中 F 是完全确定的,并且使用了整个软件堆栈(框架、箭头和 parquet 库)的完全相同的版本 - 我有多大可能得到每次 b 保存到 Parquet 时,不同主机上数据帧 b 相同的二进制表示

换句话说如何重现 Parquet 是二进制级别的?当数据逻辑上相同什么会导致二进制差异?

上下文

我正在开发一个系统,用于完全可重现和确定的数据处理和计算数据集散列以断言这些保证。

我的主要目标是确保数据集b包含相同的记录集作为数据集[=15] =] - 这当然与散列 Arrow/Parquet 的二进制表示有很大不同。不想处理存储格式的可重复性问题,我一直在内存中计算 逻辑数据哈希 。这很慢但很灵活,例如即使记录被重新排序(我认为是等效的数据集),我的哈希值也保持不变。

但是当考虑与 IPFS 和其他 content-addressable 依赖 hashes of files 的存储集成时 - 它只有一个散列(物理)而不是两个(逻辑+物理)会大大简化设计,但这意味着我必须保证 Parquet 文件是可复制的。


更新

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

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

我将继续扩展支持的类型集,因为我正在将其集成到分散式数据处理中tool我正在努力。

从长远来看,我不确定逻辑散列是最好的前进方式 - Parquet 的一个子集为了使文件布局确定性而牺牲一些效率可能是内容可寻址性的更好选择。

至少在 arrow 的实现中我期望如此,但还没有以相同的顺序验证完全相同的输入(包括相同的元数据)以产生确定性输出(出于安全原因,我们尽量不保留未初始化的值)相同的配置(假设选择的压缩算法也做出了确定性保证)。元数据或其他地方可能存在一些散列映射迭代,这也可能会破坏此假设。

正如@Pace 指出的那样,我不会依赖它并建议不要依赖它)。规范中没有任何内容可以保证这一点,并且由于编写器版本在写入文件时会保留下来,因此如果您决定升级,则可以保证会损坏。如果添加或删除额外的元数据,事情也会崩溃(我相信过去有一些针对往返数据集的重大修复,这些修复会导致不确定性)。

所以总而言之,这在今天可能行得通,也可能行不通,但即使行得通,我预计这也会非常脆弱。