迭代哈希/校验和算法



我需要在多个计算节点上生成一个非常大的文件的单个校验和,用于数据验证(xxhash, sha256或类似)。

当前,多个节点(并发)生成这个大文件:它们做一些计算,一旦完成,它们锁定文件,然后将结果写入同一个文件(文件位于并行文件系统上)。作为后处理生成校验和并不理想,因为我想在新内容在处理节点的内存中计算校验和。

我希望当一个节点准备将其数据转储到文件时,它将从sidecar文件中读取最新的校验和,用新内容更新校验和(继续以前的校验和),然后将新的校验和保存到sidecar文件。

是否有哈希/校验和算法可以做到这一点(本质上是从以前的哈希恢复其状态)

(在xxh64的情况下,我可能会转储/恢复状态结构到sidecar文件,但它本质上是内部的,所以这似乎不是一个理想的方法)

crc可以由单个块的crc拼接在一起,但加密哈希不能。

然而,即使是加密散列通常也允许增量操作。如果您的文件只是追加到(不覆盖旧的、已经散列的数据),那么您可以简单地保留散列器状态数据在'sidecar'文件中。然而,这延长了锁定时间和争用,因为要附加的块的哈希值只能在锁定和加载哈希状态之后计算,并且只有在哈希状态被写回来之后才能释放锁。

因此,需要有效地序列化追加和更新哈希操作。除非哈希更新操作(load-hash-save)通过其他方式序列化,否则仅仅保留锁是不够的,直到文件中预留了足够的字节范围,以便稍后在没有锁的情况下轻松写入。

另一种选择是使用散列树,也就是Merkle树(在这种情况下更像是树枝而不是树)。你在sidecar文件中记录偏移量、长度和单个块的哈希值,你的校验和是这个文件的哈希值,而不是大文件的哈希值。

允许预先计算追加块的哈希值。sidecar文件上的锁替换了目标文件上的锁;目标文件只需要在锁下扩展/放大,但实际的写入可以在没有锁的情况下稍后完成。

最新更新