英文:
MongoDB: Difference between resumeAt and resumeToken in change streams
问题
不同之处在于resumeAt
接受一个时间戳以恢复通知,而resumeToken
接受一个恢复令牌。
return ChangeStreamOptions.builder()
.filter(Aggregation.newAggregation(Example.class, matchOperationType))
.resumeAt(Instant.ofEpochSecond(1675303335)) // 这只是一个Unix时间戳
.resumeToken(tokenDoc) // 从先前通知中保存的恢复令牌
.returnFullDocumentOnUpdate().build();
如果应用程序崩溃/重启,最简单的方法是只传递一个合理过去时间的Unix时间戳(范围从几小时到几天),而不是构建应用程序逻辑来保存每个成功处理的最后一条消息的令牌。
英文:
What is the difference b/w the behavior of resumeAt that accepts a timestamp to resume the notifications from vs resumeToken that accepts the resume token?
return ChangeStreamOptions.builder()
.filter(Aggregation.newAggregation(Example.class, matchOperationType))
.resumeAt(Instant.ofEpochSecond(1675303335)) // this is simply a unix timestamp
.resumeToken(tokenDoc) // resume token saved from previous notification
.returnFullDocumentOnUpdate().build();
In case the application crashes/restarted would be ideal/simple to just pass in an unix timestamp of a reasonable past time (ranging from few hours to few days) vs building application logic to save the token of every last successfully processed message?
答案1
得分: 1
I think the resume token is a safer bet because time is relative.
Still if your subsequent operations are idempotent, meaning you do not have a problem consuming previously seen changes (and this should be the case anyway) probably the time should be also good.
Example logic:
// 1. Open, consume, close, save token
MongoCursor<ChangeStreamDocument<Document>> cursor = inventoryCollection.watch().iterator();
ChangeStreamDocument<Document> next = cursor.next()
BsonDocument resumeToken = next.getResumeToken();
cursor.close();
// 2. Save the resume token in the database, in case your process goes down for any reason during your pause. Otherwise, you will not know where to start resuming.
...
// 3. When you want to reopen again start from the DB saved resumeToken
cursor = inventoryCollection.watch().resumeAfter(dbSavedResumeToken).iterator();
The time window from the moment you receive the event until you save it should be very small but (with a 0.00...1 chance) it may happen the process crashes before you save the continuation _id. If you have operations that are sensitive to that time window, then those operations should be idempotent so that in case you replay an already received event your data will not be affected.
It would have been nice for the Mongo server to keep track of the current offset for all change streams and uniquely identify clients. This is not possible now and this is why Mongo provides and asks for the resume token.
英文:
I think the resume token is a safer bet because time is relative.
Still if your subsequent operations are idempotent, meaning you do not have a problem consuming previously seen changes (and this should be the case anyway) probably the time should be also good.
Example logic:
// 1. Open, consume, close, save token
MongoCursor<ChangeStreamDocument<Document>> cursor = inventoryCollection.watch().iterator();
ChangeStreamDocument<Document> next = cursor.next()
BsonDocument resumeToken = next.getResumeToken();
cursor.close();
// 2. Save the resume token in the database, in case your process goes down for any reason during your pause. Otherwise, you will not know where to start resuming.
...
// 3. When you want to reopen again start from the DB saved resumeToken
cursor = inventoryCollection.watch().resumeAfter(dbSavedResumeToken).iterator();
The time window from the moment you receive the event until you save it should be very small but (with a 0.00...1 chance) it may happen the process crashes before you save the continuation _id. If you have operations that are sensitive to that time window, then those operations should be idempotent so that in case you replay an already received event your data will not be affected.
It would have been nice for the Mongo server to keep track of the current offset for all change streams and uniquely identify clients. This is not possible now and this is why Mongo provides and asks for the resume token.
答案2
得分: 0
resumeAt 和 resumeAfter 都接受 BsonTimestamp 或 token。
文档 将它们描述为:
resumeAt - 在给定点恢复更改流。
resumeAfter - 在给定点之后恢复更改流。
实际上与使用 >
与 >=
比较时间戳的差异相同。
英文:
Both resumeAt and resumeAfter accept either a BsonTimestamp or token.
The documentation describes them as:
resumeAt - Resume the change stream at a given point.
resumeAfter - Resume the change stream after a given point.
Effectively the same difference as using >
vs >=
to compare the timestamp.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论