node.js - 为在 node.js 应用程序上运行的 mongodb 计算 n 个连接池所需的内存

标签 node.js performance mongodb amazon-ec2

我正在尝试分析运行 mongodb 的 node.js 应用程序的性能,该应用程序当前配置为使用 50 个连接池。我一直在尝试使用 Blazemeter 进行测试,将 1000 个模拟用户发送到我的端点。在较小的 amazon ec2 实例上运行(4 个 CPU 和 7.5 GB 内存,性能似乎受 CPU 限制)。当我开始迁移到一台至少有 8 个 CPU 以 pm2 集群模式运行的大型机器时,mongodb 似乎内存不足。当测试达到大约 300-500 个模拟用户时,mongo 进程将失败:

I.E.我从所有 db 查询中得到一个错误,当我尝试启动 mongo shell 时看到以下消息:

2015-10-26T23:34:56.657+0000 warning: Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused
2015-10-26T23:34:56.658+0000 Error: couldn't connect to server 127.0.0.1:27017 (127.0.0.1), connection attempt failed at src/mongo/shell/mongo.js:146
exception: connect failed

第一次出现这种情况,我也在mongo日志中发现如下错误:

exception in initAndListen: 10309 Unable to create/open lock file: /var/lib/mongodb/mongod.lock errno:13 Permission denied Is a mongod instance already running?, terminating

在以下测试中,我只看到了上述行为,但在 mongo 日志中没有看到任何错误。

在运行这些测试时,mongo 通常会在失败之前使用大约 80% 的系统内存。

以下是此端点使用的唯一 mongo 查询:

    utility.getNextId(db, "projects", function(err, counter) {
    var pid = counter.seq;
    var newProject = {
        name: projectName,
        path: "/projects/"+user.name+"/"+projectName,
        created: utility.now(),
        modified: utility.now(),
        uid: user.uid,
        pid: pid,
        ip: ip
    }

    // Hierarchy of cloned projects
    if( parentPid )
        newProject.parent = parentPid;

    db.collection("projects").insert(newProject, function(err, inserted) {
        db.collection("users").update(
            {uid: user.uid},
            {$addToSet: { projects:pid }},
            function(err,_) {
                callback(err, newProject);
            }
        );
    });
});
};

exports.getNextId = function(db, name, callback) {
db.collection("counters").findAndModify(
    {_id:name},
    [["_id","asc"]],
    {$inc : {"seq":1}},
    {upsert:true, new:true},
    function(err, object) {
        callback(err, object);
    }
);
};

大部分测试是在 amazon ec2 m4.4xlarge(16 cpu 和 64GB 内存)上完成的。

对于具有 64gb RAM 的机器,连接池大小是否为 50 到大?我认为不会。有没有一种好方法来计算 n 个连接池所需的内存量?我正在做的查询有问题吗?

编辑: 这是一个屏幕截图,显示了 mongostat 在 16cpus 和 64GB ram 的 amazon ec2 m4.4xlarge 上崩溃时的 mongostat

enter image description here

我们在顶部创建 mongo DB 并满足许多其他要求:

var mongo = require("mongodb");
var flash = require("connect-flash");
var session = require("express-session");
var auth = require("basic-auth");
var admin = require("./admin.js");

var mongoServer = new mongo.Server("localhost", 27017, {auto_recconnect:true, poolSize: 50});
var db = new mongo.Db("aqo", mongoServer, {safe:true});
var busboy = require('connect-busboy');

db.open(function(err,db) {
    if(err)
        console.warn("mongo-open err:",err);
});

编辑:这是我的用户集合索引:

[
{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "name" : "_id_",
    "ns" : "aqo.users"
},
{
    "v" : 1,
    "key" : {
        "uid" : 1
    },
    "name" : "uid_1",
    "ns" : "aqo.users"
}
]

最佳答案

虽然 50 的池大小对于具有 64GB RAM 的机器来说并不大,但 800 肯定是。这是因为您有 16 个 Node 进程实例,每个实例运行 50 个。最大连接数的默认值是可用文件描述符的 80%。如果您使用的是 Linux,则默认值为 1024,因此您已经打开了几乎最大的连接数。此外,每个连接的开销约为 10MB,因此仅用于连接就使用了大约 8GB。这显然不理想。

理想情况下,您应该尽可能多地重用连接池中的这些连接。因此,从将 poolSize 设置为默认值 5 开始您的负载测试。(实际上是 16*5=80)。您可以信任 pm2 以循环方式很好地处理负载,并且每个实例的池大小为 5 应该非常好,并为您提供最佳性能。万一5个还不够,再往上一点,直到找到合适的。

关于node.js - 为在 node.js 应用程序上运行的 mongodb 计算 n 个连接池所需的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33357518/

相关文章:

node.js - 使用 mongodb 创建数据库 node.js

node.js - Slackbot( Node ): icon_emoji feature not working

python - 为什么在语句之前检查 `if` 比在语句之后检查快得多?

javascript - 如何解决 - 等待而不是等待

javascript - node.js 中的事件循环是什么意思? javascript 事件循环或 libuv 事件循环?

javascript - Electron 应用程序中出现 Uncaught Error : Bootstrap's JavaScript requires jQuery at bootstrap. min.js :6,

java - 如何计算加密和解密算法所用的时间?

javascript - React : Paginated table vs Scrollable table for column sort 中的速度比较

javascript - MongoDB - 仅更新 DBRef 字段类型中的 $ref

javascript - NodeJS 第一个 res.body 对象在引号中