gpt4 book ai didi

java - 是什么导致 MongoDB/GridFS MD5 哈希不匹配?

转载 作者:行者123 更新时间:2023-11-30 03:30:50 29 4
gpt4 key购买 nike

我正在对 MongoDB 的 GridFS 作为二进制存储进行一些审查,在测试期间,当我验证存储的文件是时,我偶尔会遇到驱动程序(在我的例子中是 Java)抛出的异常确实保存得当。在此验证中,Java 驱动程序将计算出的刚刚存储的内容的 MD5 与 MongoDB 的 filemd5 命令返回的 MD5 进行比较。

此异常已记录,我可以正确处理它,但是:

我的问题是为什么会发生这种情况(显然存在二进制不匹配,但有什么原因导致这种情况更频繁地发生)?

我可以理解它是否发生在系统故障期间,但它似乎是随机发生的(尽管不是很频繁)。

最佳答案

终于有时间好好研究一下这个问题了,这就是我的发现!

默认情况下,mongo java 驱动程序为 mongodb 的任何和所有写入设置所谓的 NONE/UNACKNOWLEDGED 写入关注。这意味着写入 mongodb 在很大程度上是一个异步过程。驱动程序说“嘿,当你有机会时存储所有这些东西”,mongo 最终存储它,但是响应会立即返回到应用程序,因此它会继续线程。

Java 驱动程序的 Mongo GridFSFile 对象有一个名为 validate 的方法,可以在存储文件后调用该方法。此方法使用 java 驱动程序在内存中计算出的 MD5,因为流被分为 block 并发送到 mongodb,然后将其与 mongo 的 filemd5 命令的结果进行比较。当 mongo 发出 filemd5 请求时,它会获取提供的 id 并根据引用提供的 id 存在的各种二进制数组 block 的内容计算 MD5(它们一起代表存储在 GridFS 中的单个实体)。 p>

至于导致我看到驱动程序计算的 MD5 与从 mongo 返回的 MD5 之间频繁不匹配的原因,基本上默认写入关注点为 NONE,它将控制权返回给应用程序并执行 validate/filemd5 命令紧随其后,然后 mongo 处理其内容的当前状态。有可能(事实上似乎确实如此)MongoDB 在所有内容实际写入内存之前就计算了 id 的 MD5,因此有时会返回错误的 MD5。

此外,这与调试细节中看到的一致 - 一旦发生异常,我添加日志记录来查询存储的文件并读取其内容,此时它始终具有正确的内容和正确的 MD5。

解决方案是 mongo 驱动程序与 GridFS 的交互必须使用至少 ACKNOWLEDGED 的写入关注点,这意味着要写入的数据在返回到应用程序之前至少由 mongo 保存在内存中。我已经为我的测试手动设置了它,并在应用程序启动时为 GridFS 集合启用它,因为它尚未作为 spring-data 中的配置选项公开。另外值得注意的是,新的 mongo-3.x java 驱动程序有一个默认的写入问题 ACKNOWLEDGED,因此一旦我使用它,理论上我可以删除额外的引导。

至于为什么在本地从未看到过这种情况,很可能我的机器具有 mongo 所需的可用内存和处理能力,可以足够快地存储内容,以便在调用 validate 时,一切都已完成已经存在,所以返回的 MD5 是正确的。运行大量并发测试的构建代理承受的负载明显更重,并且资源可能更有限,因此 mongodb 并不总是在执行 filemd5 命令之前完成存储内容。

至于验证这个问题确实已修复,我之前曾在每个构建中看到 3-4 个测试(大约 2000 个)由于这个问题而失败,现在我已经在构建代理上运行了超过 15 组完整的测试一次也没见过。

我用来纠正这个问题的实际代码:

private static final String GRID_FS_FILES_COLLECTION_NAME = "fs.files";
private static final String GRID_FS_CHUNKS_COLLECTION_NAME = "fs.chunks";

@Autowired
protected MongoOperations mongoOperations;

mongoOperations.getCollection(GRID_FS_FILES_COLLECTION_NAME).setWriteConcern(WriteConcern.ACKNOWLEDGED);
mongoOperations.getCollection(GRID_FS_CHUNKS_COLLECTION_NAME).setWriteConcern(WriteConcern.ACKNOWLEDGED);

关于java - 是什么导致 MongoDB/GridFS MD5 哈希不匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29101248/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com