简体   繁体   English

在 ChangeStream 中收到第一个文档之前,使用 MongoDB Java 驱动程序获取恢复令牌?

[英]Get resume token with MongoDB Java driver before first document received in ChangeStream?

This question is similar to How do I resume a MongoDB ChangeStream at the first document and not just changes after I start listening but for the Java driver.这个问题类似于How do I resume a MongoDB ChangeStream at the first document 并且不仅在我开始收听之后发生变化,而且对于 Java 驱动程序也发生了变化。 This is crucial, afaik, if one needs to make sure that all documents are processed at least once.这是至关重要的,afaik,如果需要确保所有文档至少处理一次。

For example, let's say that I have a change stream (C) that subscribes to documents and sends an email based on the contents of each document.例如,假设我有一个更改 stream (C) 订阅文档并根据每个文档的内容发送 email。 But if the email sending fails or the server crashes before the email could be sent then the resume token (R) will not have been persisted.但是,如果 email 发送失败或服务器在 email 可以发送之前崩溃,则恢复令牌 (R) 将不会被持久化。 When the application is started up again it'll "watch" without a resume token and thus the document will be missed and no email sent.当应用程序再次启动时,它将在没有恢复令牌的情况下“观看”,因此将丢失文档并且不会发送 email。

Is there a supported way to get the resume token of a ChangeStream before the first change document has been received to mitigate the issue described above?是否有一种受支持的方法可以在收到第一个更改文档之前获取ChangeStream的恢复令牌以缓解上述问题?

From what I can tell from the MongoDB specification this must be supported by drivers:MongoDB 规范中我可以看出,这必须由驱动程序支持:

Drivers MUST expose a mechanism to retrieve the same resume token that would be used to automatically resume.驱动程序必须公开一种机制来检索将用于自动恢复的相同恢复令牌。

But I cannot seem to find a way to do this using the Java API.但我似乎找不到使用 Java API 的方法。 Is this possible or is there a recommended workaround?这是可能的还是有推荐的解决方法?

Note that I would very much prefer not to use startAtOperationTime which is based on a timestamp since time is fragile and clocks may be changed both on the server and client.请注意,我非常希望使用基于时间戳的startAtOperationTime ,因为时间很脆弱,并且服务器和客户端上的时钟都可能更改。

In a 4.2-compatible driver implementing the "must expose resume token" provision of the specification, each time the change stream executes a getMore, one of two things happens:在实现规范的“必须公开恢复令牌”规定的 4.2 兼容驱动程序中,每次更改 stream 执行 getMore 时,都会发生以下两种情况之一:

  • Either at least one document is returned, with each document containing a resume token at that document, or至少返回一个文档,每个文档都包含该文档的简历标记,或者
  • No documents are returned, in which case postBatchResumeToken is still provided by 4.0.7+ servers.不返回任何文档,在这种情况下 postBatchResumeToken 仍由 4.0.7+ 服务器提供。

As I recall in Java change streams have a tryNext method, you need to call that to retrieve postBatchResumeToken without blocking the application.正如我在 Java 中记得的那样,更改流有一个 tryNext 方法,您需要调用它来检索 postBatchResumeToken 而不会阻塞应用程序。 The mechanism for retrieving the current resume token (either one associated with a document or postBatchResumeToken) is driver-specific.检索当前恢复令牌(与文档或 postBatchResumeToken 关联的令牌)的机制是特定于驱动程序的。

https://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-sync/com/mongodb/client/MongoChangeStreamCursor.html is the closest documentation I can find, except I believe you would use tryNext instead of next, and if tryNext doesn't return any documents you would still read the current resume token to advance your position in the change stream. https://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-sync/com/mongodb/client/MongoChangeStreamCursor.html is the closest documentation I can find, except I believe you would use tryNext而不是下一个,如果 tryNext 没有返回任何文档,您仍然会阅读当前的恢复令牌以在更改 stream 中推进您的 position。

https://docs.mongodb.com/ruby-driver/master/tutorials/ruby-driver-change-streams/#resuming-a-change-stream may be helpful as far as resume token tracking in general although this doesn't include try_next (which Ruby driver also implements) as would be needed. https://docs.mongodb.com/ruby-driver/master/tutorials/ruby-driver-change-streams/#resuming-a-change-stream 通常可能对恢复令牌跟踪有所帮助,尽管这没有帮助根据需要包括 try_next(Ruby 驱动程序也实现)。

This would allow you to correctly resume change stream before it received any documents.这将允许您在收到任何文件之前正确恢复更改 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ。 You would store the resume token after processing documents, so you need to make progress quickly enough that you don't fall off the oplog, but postBatchResumeToken handles the case of there not being any changes for a long time without falling off the oplog.您将在处理文档存储恢复令牌,因此您需要足够快地取得进展,以免掉出 oplog,但 postBatchResumeToken 处理长时间没有任何更改而不会掉出 oplog 的情况。

You still need to start the change stream at a timestamp in the very beginning, if you do not have any resume tokens - https://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-sync/com/mongodb/client/ChangeStreamIterable.html gives startAtOperationTime as the method I'd expect you would use. You still need to start the change stream at a timestamp in the very beginning, if you do not have any resume tokens - https://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-sync /com/mongodb/client/ChangeStreamIterable.html提供 startAtOperationTime 作为我希望您使用的方法。 You could potentially provide the current clusterTime as tracked by the driver, if your driver exposes that.如果您的驱动程序公开了它,您可能会提供驱动程序跟踪的当前 clusterTime。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM