请问各位 Java 下有什么性能比较好的大文件一致性对比方法么?

2022-02-24 14:07:54 +08:00
 heavyrainn

场景是,我们需要进行结构化数据大文件的数据传输,并对数据一致性进行对比。目前采用的是 MD5 对比,但是对于 40G+的文件来说,MD5 计算耗时非常长,所以希望能找到一种快速高效且基于 JAVA 实现的一致性对比方案,请大家帮出出主意,非常感谢大家

2982 次点击
所在节点    Java
19 条回复
msg7086
2022-02-24 14:15:37 +08:00
MD5 的计算速度已经很快,所以你可以考虑换个 SSD 。
如果要再提升哈希速度的话,换用 xxhash 试试。
beetlerx
2022-02-24 14:18:34 +08:00
分段计算,比如 40G 文件只计算其中 20G 的 md5, 读取文件流的时候读 1M 跳 1M
3dwelcome
2022-02-24 14:24:57 +08:00
@beetlerx 估计不行吧,楼主的目的就是需要确认保存磁盘的数据,有没有损坏。

你这样一来,万一跳过损坏区域咋办?
wangyu17455
2022-02-24 14:31:15 +08:00
双指针逐字节比较?
xuyang2
2022-02-24 14:47:50 +08:00
Opportunity
2022-02-24 14:48:38 +08:00
你都要进行数据传输了,我不信网速比计算 MD5 还快,同一个流一边读取发送一边算 MD5 ,传完文件再把 MD5 发过去,另一边收的同时计算,最后校验就可以了。
cpstar
2022-02-24 15:08:50 +08:00
发送端在保存的时候即创建摘要,再次读取传输的时候直接传送摘要。
接收端在接收的时候即创建摘要,之后两者匹配。

场景描述不详细,还需要 OP 补充。
flyingghost
2022-02-24 15:24:30 +08:00
hash 计算再怎么长都不会比网络传输时间长。
因此,分片校验并传输,利用传输时间进行其他分片的 hash 计算完全足够。
以及,分片的好处不止校验速度,传输出错后的重传也依赖分片。

分片唯一的缺点是不方便做完整文件的“秒传”,但文件共享度低的场景下其实不存在秒传。

另外一个办法就是提前计算好 hash 放在大文件旁边。
heavyrainn
2022-02-24 16:25:43 +08:00
@flyingghost
@cpstar
@Opportunity
@beetlerx
非常抱歉,的确是我场景描述的不清楚,我的场景是,A 端生成文件->A 端生成 MD5->A 端压缩文件->A 端 SFTP 推送文件-A 端传输 MD5 记录文件->B 端解压缩文件->B 端计算 MD5->B 端对比 MD5 验证文件完整性
现在我的问题在于,B 端接收文件后,需要自己再算一手 MD5 ,然后和 A 端提供的 MD5 进行对比。我希望能够缩短 B 端的数据对比时间,保证每个传输流在能够压缩在 10 分钟内完成,但是 40G+的文件,在 B 端进行 MD5 计算时最长可能需要消耗半小时,无法满足我们对传输对比耗时的需求,所以请各位帮忙
cpstar
2022-02-24 16:50:38 +08:00
如我所猜,耗时点(效率瓶颈)产生在接收端的创建摘要过程,因为我觉得 A 端保存并摘要在整个流程中是一个异步的,不会影响。而可能 B 端接收是一个同步的事件,需要考虑摘要计算的影响。

那么我觉得你最好不要用 sftp 而是自己实现传输过程,在接收的时候,边接收边计算,甚至采用楼内建议,分片外加并行。如果是结构化的数据文件,分片比较 easy 吧。
xuyang2
2022-02-24 16:54:54 +08:00
https://stackoverflow.com/questions/30056566/how-to-perform-checksums-during-a-sftp-file-transfer-for-data-integrity

> With the SFTP, running over an encrypted SSH session, there's negligible chance the file contents could get corrupted while transferring. The SSH itself does data integrity verification.
git00ll
2022-02-24 16:55:39 +08:00
md5 已经很快了。剩下的编写能充分利用多核的代码,服务器增加核心数。
Nitroethane
2022-02-24 16:59:44 +08:00
@heavyrainn A 端压缩之后再计算 MD5 ,这样情况下 A 、B 两端计算量都比较小
iyear
2022-02-24 17:02:34 +08:00
bt 好像就是分片校验保证完整性的,我不太懂这方面,只是刚好想起来
wy315700
2022-02-24 17:02:42 +08:00
试试 CRC32
knives
2022-02-25 01:12:06 +08:00
分片传输,然后分片比对哈希,最后再对所有分片的哈希做一个总体哈希验算。具体可以参考:

https://docs.aws.amazon.com/zh_cn/amazonglacier/latest/dev/checksum-calculations.html

https://zh.wikipedia.org/wiki/%E5%93%88%E5%B8%8C%E6%A0%91
oneegg
2022-02-25 10:50:07 +08:00
分片计算就好了。这个东西没办法的,
Brentwans
2022-02-25 15:31:49 +08:00
如果是防止数据传输异常,那么 crc32 做 checksum 足够了。
ysc3839
2022-02-25 19:09:24 +08:00
@wangyu17455 #4 这么做反而会慢,不管是机械硬盘还是固态硬盘都是顺序读取性能最好,两边同时读的话就变成随机读取了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/836151

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX