【问题标题】:Repetitive Node.js requests to MongoDB slow down eventually对 MongoDB 的重复 Node.js 请求最终会变慢
【发布时间】:2016-09-27 18:56:01
【问题描述】:

我有数据进入 MongoDB 集合 rmc 并且它正在被更新,即我有一个点与我的设备的最新纬度和经度。

从 Node.js,我想每隔 100 ms 查询一次该集合(以模拟实时)并使用更新后的纬度/经度更新地图。

一开始我的性能很好,但在我的集合中更新了数据之后或者只是一段时间后,性能开始变得非常糟糕。

我做错了什么?我能以更好的方式做事吗?我似乎无法弄清楚是 MongoDB 还是 Node 还是 Mongoose

用户转到index.html,它会获取一个 HTML 页面。在 HTML 中,我每 100 毫秒请求一个页面:

function updateData() {
  $.getJSON("/data", function(json) {
    dosomething()
    interval = setTimeout(updateData, 100);
  })
};

updateData();

还有我的 index.js:

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: "test" });
});

router.get('/data', function(req, res, next) {
  var db = req.db;
  Json.find({}).select({}).lean().exec(function(e,docs){
    res.json(docs);
  });
});

一切都很好,突然之间,经历了巨大的延迟:

GET /data 304 1.644 ms - -
GET /data 304 1.738 ms - -
GET /data 304 1.685 ms - -
GET /data 304 1.693 ms - -
GET /data 304 1.624 ms - -
GET /data 304 1.645 ms - -
GET /data 304 1.873 ms - -
GET /data 304 1.607 ms - -
GET /data 304 1.638 ms - -
GET /data 304 1.610 ms - -
GET /data 304 1.734 ms - -
GET /data 304 1.736 ms - -
GET /data 304 1.660 ms - -
GET /data 304 1.634 ms - -
GET /data 304 15.265 ms - -
GET /data 304 10.535 ms - -
GET /data 304 1.740 ms - -
GET /data 304 70.184 ms - -
GET /data 304 69.037 ms - -
GET /data 304 58.620 ms - -
GET /data 304 75.053 ms - -
GET /data 304 72.292 ms - -
GET /data 304 92.447 ms - -
GET /data 304 95.270 ms - -
GET /data 304 448.057 ms - -
GET /data 304 567.309 ms - -
GET /data 304 683.199 ms - -
GET /data 304 731.952 ms - -
GET /data 304 1102.502 ms - -
GET /data 304 1770.029 ms - -
GET /data 304 1051.307 ms - -
GET /data 304 1059.791 ms - -

【问题讨论】:

  • 所以我认为 node.js / mongoose 在每次调用后都会在内存中保留某种工件,因此我的服务器很快就会饱和。有什么办法可以在脚本执行时清理内存?
  • 我使用 mongoskin 获得了更好的性能,但是,过了一会儿,有些东西填满了,并且发现了上述行为。仅供参考,我完全注释了我的代码,并且只触发了对 /data 路由的调用以进行故障排除
  • 不是您问题的答案,但您应该考虑使用 Redis 缓存而不是一遍又一遍地查询相同的数据,您将获得更好的性能。但是,我认为您的代码没有任何问题,并且不应该发生这种减速。
  • 您能否发布一段时间内的 CPU 和 RAM 使用情况?对于 node 和 mongodb 进程。
  • 您应该尝试使用 Node.js MongoDB 驱动程序复制问题...如果问题没有发生,至少您会知道问题与 Mongoose 有关。

标签: javascript node.js mongodb mongoose


【解决方案1】:

要提高 mongoDB 性能,您可以执行以下 2 件事:

  1. 调整连接池;这样,您的代码将重用现有连接,而不是每次执行某些操作时创建新连接,默认情况下它 5 尝试缩放它。

  2. 在您的集合中创建索引;创建一个唯一/复合索引,这肯定会提高您的查询性能。

此外,您可以运行 explain 命令来查看您的整个查询执行和分析。

看看这个:MongoDB Performance

【讨论】:

    【解决方案2】:

    我认为您正在将输出传递给许多功能不大的函数。此外,如果输出很小,那么将所有数据作为响应发送似乎是可以的。尝试将您的代码修改为

    const docs = await Json.find({})
    res.json(docs)
    

    您不需要lean() 或select()。他们什么都不做

    【讨论】:

      【解决方案3】:

      您必须在代码中以及完整代码中查看查询的执行时间(可以为此使用控制台语句)。并查看占用时间的查询或任何其他代码。同时时间监控cpu使用情况并查看哪个进程占用了多少资源。 您可以查看任何 mongodb 查询的执行统计信息 https://docs.mongodb.com/manual/reference/operator/meta/explain/

      另外在开发中以调试模式运行 mongoose。

      mongoose.set('debug', true);
      

      【讨论】:

        【解决方案4】:

        分析节点应用程序以找出问题的来源可能有不同的方法。使用本机节点,您可以尝试运行您的应用程序:

         node --prof <entrypoint>.js
        

        然后尝试运行测试以允许节点收集一些数据,完成后将生成一个文件,该文件必须转换为具有更好的人类友好输出的文件

        node --prof-process <file_generate>.log > processed.txt
        

        进入processed.txt,您可以找到代码的哪些部分花费了更多的CPU时间,从而可以指出问题可能出在哪里。

        关于更详细的信息,节点文档中有一个很好的条目关于分析分析文件https://nodejs.org/en/docs/guides/simple-profiling/

        【讨论】:

          猜你喜欢
          • 2015-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-14
          • 2014-06-11
          • 2018-09-15
          • 1970-01-01
          • 2021-07-01
          相关资源
          最近更新 更多