MongoDB Change Events 可以被认为是独一无二的吗? [英] Can MongoDB Change Events be considered unique?

查看:43
本文介绍了MongoDB Change Events 可以被认为是独一无二的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说明

我正在利用 MongoDb 更改流(C# MongoDB.Driver v2.12.0)来跟踪单个集合的更改.在实验用例中,集合存储有关线程执行的信息.

一个线程有两个属性:

  • 状态 - 正在运行、已阻止或已完成
  • BlockedCount - 阻塞线程数

在执行期间,线程可以产生子线程并被阻塞,直到所有子线程都没有完成.每当子线程完成其执行时,它通过递减父线程的 BlockedCount 来更新数据库.一旦 BlockedCount 下降到 0,父线程应该继续执行.

订阅变更流的代码:

var pipeline = new EmptyPipelineDefinition>().Match(change => change.OperationType == ChangeStreamOperationType.Insert ||change.OperationType == ChangeStreamOperationType.Update ||change.OperationType == ChangeStreamOperationType.Replace).AppendStage、ChangeStreamDocument、ChangeStreamOutputWrapper("{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}");var 选项 = 新的 ChangeStreamOptions{FullDocument = ChangeStreamFullDocumentOption.UpdateLookup};使用(var cursor = await coll.WatchAsync(管道,选项,取消令牌)){等待 cursor.ForEachAsync(异步更改 =>{//等待一些处理程序例程}, 取消令牌);}

问题

我注意到的是,即使更新操作完全相同,更改事件也可能不同.为了更好地解释这一点,这里有一个例子:

有 1 个父线程和 3 个子线程完成它们的执行,观察到两种不同的行为:

  • 父线程的 3 个不同的更新事件:

    • 状态":BLOCKED",BlockedCount";:2
    • 状态":BLOCKED",BlockedCount";: 1
    • 状态":BLOCKED",BlockedCount";:0
  • 父线程的 3 个相同的更新事件:

    • 状态":BLOCKED",BlockedCount";:0
    • 状态":BLOCKED",BlockedCount";:0
    • 状态":BLOCKED",BlockedCount";:0

问题

  1. 这是否属于正常行为?
  2. 是否有某种配置可以防止这种情况发生,并且仅触发最新"更新?

解决方案

是的,这是预期的行为.文档(link)指出:><块引用>

fullDocument 文档表示更新文档的最新多数提交版本.fullDocument 文档可能与更新操作时的文档不同,具体取决于更新操作和文档查找之间发生的交错多数提交操作的数量.

据我所知,没有办法克服或调整这种行为.但是,您可以做的是直接读取updateDescription,手动跟踪更改.如果 BlockedCount 仅被设置(即,未删除并稍后重新添加),则不会很复杂.

Description

I am utilizing the MongoDb change stream (C# MongoDB.Driver v2.12.0) to track changes on a single collection. In an experimental use case the collection stores information about execution of threads.

A thread has two properties:

  • Status - RUNNING, BLOCKED or COMPLETED
  • BlockedCount - number of blocking threads

During its execution, a thread can spawn children threads and be blocked until all of the children are not completed. Whenever a children thread completes its execution, it updates the database by decrementing the BlockedCount of the parent. Once the BlockedCount drops to 0, the parent thread should continue its execution.

Code for subscribing to change stream:

var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<T>>()
                    .Match(change => change.OperationType == ChangeStreamOperationType.Insert ||
                                     change.OperationType == ChangeStreamOperationType.Update ||
                                     change.OperationType == ChangeStreamOperationType.Replace)
                    .AppendStage<ChangeStreamDocument<T>, ChangeStreamDocument<T>, ChangeStreamOutputWrapper<T>>(
                                     "{ $project: { '_id': 1, 'fullDocument': 1, 'ns': 1, 'documentKey': 1 }}");

var options = new ChangeStreamOptions
{
    FullDocument = ChangeStreamFullDocumentOption.UpdateLookup
};

using (var cursor = await coll.WatchAsync(pipeline, options, cancellationToken))
{
    await cursor.ForEachAsync(async change =>
    {
        // await some handler routine
    }, cancellationToken);
}

Issue

What I have noticed is that the change events can be different even if the update operations are exactly the same. To better explain this, here is an example:

There is 1 parent thread and 3 children threads completing their execution, there are two different behaviors observed:

  • 3 distinct update events for the parent thread:

    • "Status" : "BLOCKED", "BlockedCount" : 2
    • "Status" : "BLOCKED", "BlockedCount" : 1
    • "Status" : "BLOCKED", "BlockedCount" : 0
  • 3 identical update events for the parent thread:

    • "Status" : "BLOCKED", "BlockedCount" : 0
    • "Status" : "BLOCKED", "BlockedCount" : 0
    • "Status" : "BLOCKED", "BlockedCount" : 0

Questions

  1. Is this considered a normal behavior?
  2. Is there some kind of configuration that would prevent this, and fire only the 'latest' update?

解决方案

Yes, that is the expected behavior. The documentation (link) states, that:

The fullDocument document represents the most current majority-committed version of the updated document. The fullDocument document may vary from the document at the time of the update operation depending on the number of interleaving majority-committed operations that occur between the update operation and the document lookup.

And as far as I know, there's no way to overcome nor adjust this behavior. However, what you can do, is to read updateDescription directly, manually tracking the changes. It's not going to be complex if the BlockedCount is only being set (i.e., not removed and re-added later).

这篇关于MongoDB Change Events 可以被认为是独一无二的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆