我想读取大型MongoDb集合中的所有文档(事件)(例如数百万个文档),并同时处理它们(反序列化每个事件)。可以使用MongoDb C#驱动程序轻松完成此操作,但是以最佳方式(在我的情况下,最佳方式是最快的方式)很难做到这一点。
通过几次迭代,我提出了一种解决方案,其中包括批读取,双缓冲和事件的并行反序列化。
在代码中可以看到,事件以1000批读取,而我在此处使用了双缓冲读取(同时读取新批,同时并行反序列化旧批并通过IEnumerable返回)。
public IEnumerable<IReadOnlyList<IDomainEvent>> LoadAll()
{
using (var cursor = _mongoCollection.FindSync(Filter.Empty, FindOptionsFor1000BatchSize))
{
cursor.MoveNextAsync().Wait();
Task<bool> cursorTask;
do
{
var events = cursor.Current;
cursorTask = cursor.MoveNextAsync();
yield return events.AsParallel().Select(e => e.ToDomainEvent()).ToList();
} while (cursorTask.Result);
}
}
通过这种方法,我能够在8秒钟内读取并反序列化1 000 000个事件。详细结果:
- 批量读取(1m个事件)-15秒
- 批量读取并并行化(1m个事件)-11秒
- 具有并行化和双缓冲(1m个事件)的批量读取-8秒
我以不同的批次大小进行游戏,在我的情况下,1000是最佳大小。
是否有更快的方式从MongoDb中读取事件?