NodeJS mongodb:使用全局连接还是本地连接

3
我有一组nodejs脚本,用于对mongodb进行大量的查询、插入和更新操作。我面临一个选择,是使用全局的db连接对象并将其传递给不同的函数,还是在每个函数中获取自己的db连接对象并在完成后关闭它。
1. 全局的db连接对象。优点是只需要建立一次连接即可,后续的函数调用将通过节省连接到数据库所需的时间来提高性能。问题在于很难确定何时关闭连接。我的脚本很复杂,有几层函数调用。有些函数在回调函数触发后仍需要执行进一步的任务,如果不关闭连接,则父脚本无法知道何时退出。
2. 在每个函数中建立一个新的db连接对象。这种方法最大的担忧是性能。我测试了每个连接大约需要60毫秒才能建立。如果在所有函数调用中添加这个连接,可能会导致巨大的性能下降。
我倾向于采用第一种方法,但需要找出一种方法使父脚本在完成所有任务后退出。
以下是伪代码,以说明脚本的高级结构。
//db is a global connection object. 
function entry_point(db) {
    task1(db, callback){
        loop {
            sub_task(db, callback2){
                dosomething
                callback2
                dosomeotherthings
            }
            callback
        }
        dosomethingagain
    }

    task2(db, callbac) //Similar call trees, maybe with more levels. 
    task3.... 
    ....
}
2个回答

2
你可以使用 async 来运行异步任务...最后关闭全局的mongodb连接。例如:

async.auto( {
        'mongo': [ function( callback ) {
            /// initiate mongodb and call: callback( null );
        } ],
        'task1': [ 'mongo', function( callback ) {
            // this task wait for 'mongo' to be initiated
            // run your functions/code and call: callback( null );
        } ],
        'task2': [ 'mongo', function( callback ) {
            /// same as task1
        } ],
        'task3': [ 'mongo', 'task1', function( callback ) {
            /// will run after 'mongo' and 'task1' has completed
        } ],
    },
    function( err, rets ) {
        /// all task are done
        /// now you can close your mongodb connection / process.exit( 0 );
    }
);

Husanu,谢谢。我之前正在探索async。到目前为止,我看到的例子,包括你的,都只是在一个层级的任务中使用async。您是否有应用多层次async的经验?我在我的主帖中添加了一些伪代码来说明我的脚本结构。从那里你可以看到我可能需要在async内部应用async。这会有问题吗?有什么陷阱我应该注意或高级最佳实践等吗?谢谢! - Lee

2
适当的方法是使用全局连接,您可以在整个应用程序中重复使用它。
驱动程序具有内置的连接池(默认大小为5),可重用现有集合。
此外,为了实现高可用性,您的应用程序将连接到副本集(或多个mongos)并使用多个TCP套接字支持故障转移。创建新套接字非常昂贵,因此您不想“创建新客户端”。
您可以在此处找到更多信息:

Tug,同意全局连接更好的观点。在避免“创建新客户端”方面,你指的是创建MongoClient还是打开连接?从我的测试中看,创建MongoClient对象几乎不耗费时间,但打开连接却很耗费时间。var mongoClient = new MongoClient(new Server('localhost', 27017)); // 耗时1ms; mongoClient.open(function(err, mongoClient) {}); // 耗时约40-50ms。 - Lee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接