计算在node.js app上运行的mongodb的n个连接池所需的内存

Mik*_*012 17 performance amazon-ec2 mongodb node.js

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

IE我从所有数据库查询中收到错误,当我尝试启动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
Run Code Online (Sandbox Code Playgroud)

第一次发生这种情况时,我还在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
Run Code Online (Sandbox Code Playgroud)

在以下测试中,我只看到了上述行为,但没有看到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);
    }
);
};
Run Code Online (Sandbox Code Playgroud)

大多数测试是在亚马逊ec2 m4.4xlarge(16 cpus和64GB ram)上完成的.

对于具有64 GB RAM的计算机,连接池大小是50到大吗?我想不会.有没有一种很好的方法来计算n个连接池所需的内存量?我的问题是我的问题吗?

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

在此输入图像描述

我们在顶部创建了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);
});
Run Code Online (Sandbox Code Playgroud)

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

[
{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "name" : "_id_",
    "ns" : "aqo.users"
},
{
    "v" : 1,
    "key" : {
        "uid" : 1
    },
    "name" : "uid_1",
    "ns" : "aqo.users"
}
]
Run Code Online (Sandbox Code Playgroud)

Rah*_*bub 7

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

理想情况下,您应该尽可能地在连接池中重用这些连接.因此,将poolSize设置为默认值5即开始负载测试.(实际上16*5 = 80).您可以信任pm2以循环方式很好地处理负载,并且每个实例的池化大小应该非常精细并且为您提供最佳性能.如果5是不够的,请稍微向上,直到找到合适的东西.

  • "每个连接都有~10MB的开销"评论已经过时了.对于MongoDB 2.0,看起来它在2011年7月左右减少到大约1MB (2认同)