首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >计算在node.js应用上运行的mongodb的n个连接池所需的内存

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

Stack Overflow用户
提问于 2015-10-27 07:43:27
回答 2查看 2.7K关注 0票数 17

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

也就是说,我从所有的数据库查询中得到了一个错误,当我试图启动mongo shell时,我看到了下面的消息:

代码语言:javascript
复制
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日志中发现了以下错误:

代码语言:javascript
复制
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查询:

代码语言:javascript
复制
    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);
    }
);
};

大部分测试是在亚马逊ec2 m4.4xlarge (16个cpus和64 16内存)上完成的。

对于具有64 to的机器,50的连接池大小是不是太大了?我可不这么认为。有没有好的方法来计算n个连接池所需的内存量?我的问题是我正在进行的查询吗?

编辑:这是一张屏幕截图,显示了mongostat在亚马逊ec2 m4.4xlarge上崩溃时的状态,它有16cpu和64 on的内存。

我们在顶部创建mongo DB和许多其他需求:

代码语言:javascript
复制
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);
});

编辑:以下是我对users集合的索引:

代码语言:javascript
复制
[
{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "name" : "_id_",
    "ns" : "aqo.users"
},
{
    "v" : 1,
    "key" : {
        "uid" : 1
    },
    "name" : "uid_1",
    "ns" : "aqo.users"
}
]
EN

回答 2

Stack Overflow用户

发布于 2015-11-03 03:54:35

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

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

票数 7
EN

Stack Overflow用户

发布于 2015-11-03 07:28:22

您有大量的排队读操作,但成功进行的读操作并不多。我的猜测是,users集合中的uid没有索引(因为您在其他地方通过_id查询,Mongo会自动对其进行索引)。

看起来你把Mongo作为一个独立的服务器运行,它被设计成作为副本集运行,我不确定这会导致什么问题,但我猜他们没有对单独工作的Mongo实例做太多的测试,所以可能会有内存问题。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33357518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档