MongoDB: 变更流中resumeAt和resumeToken的区别

huangapple go评论49阅读模式
英文:

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&lt;ChangeStreamDocument&lt;Document&gt;&gt; cursor = inventoryCollection.watch().iterator();
ChangeStreamDocument&lt;Document&gt; 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 - 在给定点之后恢复更改流。

实际上与使用 &gt;&gt;= 比较时间戳的差异相同。

英文:

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 &gt; vs &gt;= to compare the timestamp.

huangapple
  • 本文由 发表于 2023年2月10日 05:34:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404637.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定