【问题标题】:Severe performance drop with MongoDB Change StreamsMongoDB Change Streams 导致性能严重下降
【发布时间】:2018-07-02 20:58:03
【问题描述】:

我想获得有关 Node.js 中 MongoDB 数据库更改的实时更新。

单个 MongoDB 更改流几乎可以立即发送更新通知。但是,当我打开多个 (10+) 个流时,数据库写入和通知到达之间会出现大量延迟(长达几分钟)。

这就是我设置变更流的方式:

let cursor = collection.watch([
  {$match: {"fullDocument.room": roomId}},
]);
cursor.stream().on("data", doc => {...});

我尝试了另一种设置流的方法,但速度一样慢:

let cursor = collection.aggregate([
  {$changeStream: {}},
  {$match: {"fullDocument.room": roomId}},
]);
cursor.forEach(doc => {...});

在收集性能数据的同时,自动化流程会将小型文档插入集合中。

一些额外的细节:

  • 打开流游标数:50
  • 写入速度:100 文档/秒(使用 insertMany 批量 10 个)
  • 运行时间:100 秒
  • 平均延迟:7.1 秒
  • 最大延迟:205 秒(不是错字,超过三分钟)
  • MongoDB 版本:3.6.2
  • 集群设置 #1:MongoDB Atlas M10(3 个副本集)
  • 集群设置 #2:DigitalOcean Ubuntu box + Docker 中的单实例 mongo 集群
  • Node.js CPU 使用率:

两种设置都会产生相同的问题。这里会发生什么?

【问题讨论】:

  • 您是否检查过您是否拥有所有需要的索引? IE。 “fullDocument.room”我想这需要一个索引
  • 不,我没有任何索引。我真的不明白索引如何帮助整理新插入的项目。但我会试一试。
  • 更新:在room 上添加了一个索引,没有任何改变。
  • 你有没有找到任何提示?
  • 不幸的是,没有。 :( 我要开始赏金了。

标签: mongodb


【解决方案1】:

MongoDB 的 Node.js 客户端中的default connection pool size 为 5。由于每个更改流游标都会打开一个新连接,因此连接池至少需要与游标数量一样大.

在 Node Mongo 驱动程序的 3.x 版中,使用“poolSize”:

const mongoConnection = await MongoClient.connect(URL, {poolSize: 100});

在 Node Mongo Driver 的 version 4.x 中使用 'minPoolSize' 和 'maxPoolSize':

const mongoConnection = await MongoClient.connect(URL, {minPoolSize: 100, maxPoolSize: 1000});

(感谢 MongoDB Inc. 调查this issue。)

【讨论】:

  • 谢谢。所以如果我正在观看 5 个集合,这些不同的集合也会打开与数据库的连接?
  • @0.sh 是的,这是我的理解。值得一提的是,即使您使用 5 个不同的流观看同一个集合,它也会打开 5 个连接。不知道为什么。
  • 而恼人的事实是,如果 poolSize 等于 db.serverStatus().connections.current 应用程序将大幅减速
  • 这很令人失望,但值得注意的是,至少在 4.2 及更高版本上,您可以在数据库上打开更改流,然后使用查询来选择您想要的集合;因此你可以为数据库中的所有集合做一个单一的流,你只需要在你自己的代码中解复用它们
  • 嗨@taxilian,可以打开的变更流的最大数量是多少?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多