C# 如何在同一集合的多个MongoDB观察程序之间分配工作负载?
我想知道是否可以为一个集合启动多个观察者 在我的例子中,我启动了多个线程来监视一个集合,但是mongo会将相同的文档返回给所有观察者 如何让MongoDB在这些已启动的线程之间拆分文档负载 螺纹起动器:C# 如何在同一集合的多个MongoDB观察程序之间分配工作负载?,c#,mongodb,C#,Mongodb,我想知道是否可以为一个集合启动多个观察者 在我的例子中,我启动了多个线程来监视一个集合,但是mongo会将相同的文档返回给所有观察者 如何让MongoDB在这些已启动的线程之间拆分文档负载 螺纹起动器: for (var i = 0; i < 4; i++) { ThreadMongoDB thWork = new ThreadMongoDB(_config, _serviceProvider); thWork
for (var i = 0; i < 4; i++)
{
ThreadMongoDB thWork = new ThreadMongoDB(_config, _serviceProvider);
thWork.ThreadName = "TH-" + i.ToString();
Thread th = new Thread(thWork.Process);
await Task.Run(() =>
{
th.Start();
});
}
for(变量i=0;i<4;i++)
{
ThreadMongoDB thWork=新的ThreadMongoDB(_config,_serviceProvider);
thWork.ThreadName=“TH-”+i.ToString();
螺纹th=新螺纹(thWork.Process);
等待任务。运行(()=>
{
th.Start();
});
}
ThreadMongoDB类中的代码:
public class ThreadMongoDB
{
readonly IMongoDatabase _db;
readonly Executer _exec;
public string ThreadName { get; set; }
public ThreadMongoDB(IConfiguration iconfig, IServiceProvider serviceProvider)
{
var typeConn = iconfig["TypeConn"];
var client = new MongoClient(iconfig[$"{typeConn}:cnnMain"]);
_db = client.GetDatabase(iconfig[$"{typeConn}:dbMain"]);
_exec = new Executer(iconfig, serviceProvider);
}
public void Process()
{
var options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
var pipeline = new EmptyPipelineDefinition<ChangeStreamDocument<WorkerQueue>>()
.Match("{ operationType: { $in: [ 'replace', 'insert', 'update' ] }}");
//.Match("{ $or: [ {operationType: 'replace' }, { operationType: 'insert' }, { operationType: 'update' } ] }");
using (var pilotQueueStream = _db.GetCollection<WorkerQueue>("one_queue_pilot")
.Watch(pipeline, options).ToEnumerable().GetEnumerator())
{
while (true)
{
pilotQueueStream.MoveNext();
WorkerQueue currentReg = pilotQueueStream.Current.FullDocument;
if (currentReg != null)
{
if (!currentReg.boolDone)
{
_exec.Execute(ThreadName, currentReg);
}
}
}
}
}
}
}
公共类ThreadMongoDB
{
只读IMongoDatabase_db;
只读执行器_exec;
公共字符串ThreadName{get;set;}
public ThreadMongoDB(IConfiguration iconfig,IServiceProvider服务提供商)
{
var typeConn=iconfig[“typeConn”];
var client=newmongoclient(iconfig[$”{typeConn}:cnnMain“]);
_db=client.GetDatabase(iconfig[$”{typeConn}:dbMain“]);
_exec=新的执行器(iconfig,serviceProvider);
}
公共程序()
{
var options=new ChangeStreamOptions(){FullDocument=ChangeStreamFullDocumentOption.UpdateLookup};
var pipeline=new EmptyPipelineDefinition()
.Match(“{operationType:{$in:['replace','insert','update']}”);
//.Match(“{$or:[{operationType:'replace'},{operationType:'insert'},{operationType:'update'}]}”);
使用(var pilotqueestream=\u db.GetCollection(“一个队列\u导频”)
.Watch(管道,选项).ToEnumerable().GetEnumerator())
{
while(true)
{
pilotQueueStream.MoveNext();
WorkerQueue currentReg=pilotQueueStream.Current.FullDocument;
如果(currentReg!=null)
{
如果(!currentReg.boolDone)
{
_exec.Execute(ThreadName,currentReg);
}
}
}
}
}
}
}
我想知道是否可以为一个集合启动多个观察者
在我的例子中,我启动了多个线程来监视一个集合,但是mongo会将相同的文档返回给所有观察者
这是预期的结果:您可以有多个变更流处于活动状态,但每个流都是独立的,并且观察者之间没有协调。观看相同的流将导致相同的事件
如何让MongoDB在这些已启动的线程之间拆分文档负载
此要求必须在您的应用程序中处理
如果观察者正在为更改流事件做重要的处理,并且希望分配工作负载,则需要考虑的一些方法是:
- 让变更流观察者将事件推送到中心,以便多个工作线程可以声明和处理队列中的作业。这是一种典型的批处理模式
- 让每个观察者包括一个
阶段,该阶段过滤要处理的变更流事件的不同子集。这种方法需要一些计划来确保事件不会重叠,并且如果某些事件类型需要比其他类型更多的工作人员,那么这种方法的可伸缩性就会降低$match
在实施这两种方法之前,肯定值得确认您的工作负载需要更多的工作人员/线程。谢谢您的回答。在实现watcher之前,我正在使用find()阅读这个工作队列。第一个命令有多个线程,但后来我发现这些监视程序将触发进程,而不必将集合集中起来。因此,我将保留一个观察者,如果卷增加,我将返回到使用多个线程读取集合。非常感谢你。