场景是,我们需要进行结构化数据大文件的数据传输,并对数据一致性进行对比。目前采用的是 MD5 对比,但是对于 40G+的文件来说,MD5 计算耗时非常长,所以希望能找到一种快速高效且基于 JAVA 实现的一致性对比方案,请大家帮出出主意,非常感谢大家
1
msg7086 2022-02-24 14:15:37 +08:00
MD5 的计算速度已经很快,所以你可以考虑换个 SSD 。
如果要再提升哈希速度的话,换用 xxhash 试试。 |
2
beetlerx 2022-02-24 14:18:34 +08:00
分段计算,比如 40G 文件只计算其中 20G 的 md5, 读取文件流的时候读 1M 跳 1M
|
4
wangyu17455 2022-02-24 14:31:15 +08:00 1
双指针逐字节比较?
|
5
xuyang2 2022-02-24 14:47:50 +08:00
|
6
Opportunity 2022-02-24 14:48:38 +08:00
你都要进行数据传输了,我不信网速比计算 MD5 还快,同一个流一边读取发送一边算 MD5 ,传完文件再把 MD5 发过去,另一边收的同时计算,最后校验就可以了。
|
7
cpstar 2022-02-24 15:08:50 +08:00
发送端在保存的时候即创建摘要,再次读取传输的时候直接传送摘要。
接收端在接收的时候即创建摘要,之后两者匹配。 场景描述不详细,还需要 OP 补充。 |
8
flyingghost 2022-02-24 15:24:30 +08:00
hash 计算再怎么长都不会比网络传输时间长。
因此,分片校验并传输,利用传输时间进行其他分片的 hash 计算完全足够。 以及,分片的好处不止校验速度,传输出错后的重传也依赖分片。 分片唯一的缺点是不方便做完整文件的“秒传”,但文件共享度低的场景下其实不存在秒传。 另外一个办法就是提前计算好 hash 放在大文件旁边。 |
9
heavyrainn OP @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 计算时最长可能需要消耗半小时,无法满足我们对传输对比耗时的需求,所以请各位帮忙 |
10
cpstar 2022-02-24 16:50:38 +08:00
如我所猜,耗时点(效率瓶颈)产生在接收端的创建摘要过程,因为我觉得 A 端保存并摘要在整个流程中是一个异步的,不会影响。而可能 B 端接收是一个同步的事件,需要考虑摘要计算的影响。
那么我觉得你最好不要用 sftp 而是自己实现传输过程,在接收的时候,边接收边计算,甚至采用楼内建议,分片外加并行。如果是结构化的数据文件,分片比较 easy 吧。 |
11
xuyang2 2022-02-24 16:54:54 +08:00 1
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. |
12
git00ll 2022-02-24 16:55:39 +08:00
md5 已经很快了。剩下的编写能充分利用多核的代码,服务器增加核心数。
|
13
Nitroethane 2022-02-24 16:59:44 +08:00 via iPhone
@heavyrainn A 端压缩之后再计算 MD5 ,这样情况下 A 、B 两端计算量都比较小
|
14
iyear 2022-02-24 17:02:34 +08:00 via Android
bt 好像就是分片校验保证完整性的,我不太懂这方面,只是刚好想起来
|
15
wy315700 2022-02-24 17:02:42 +08:00
试试 CRC32
|
16
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 |
17
oneegg 2022-02-25 10:50:07 +08:00 via iPhone
分片计算就好了。这个东西没办法的,
|
18
Brentwans 2022-02-25 15:31:49 +08:00
如果是防止数据传输异常,那么 crc32 做 checksum 足够了。
|
19
ysc3839 2022-02-25 19:09:24 +08:00
@wangyu17455 #4 这么做反而会慢,不管是机械硬盘还是固态硬盘都是顺序读取性能最好,两边同时读的话就变成随机读取了。
|