awaage
awaage

Reputation: 2769

Node.js lsof - many open DB connections

When I run "lsof | grep node" on my server (running a node.js app), I get about 1000+ lines (db connections to port 9160). Each line looks like this:

node      17006      root  160u     IPv4         1362100969       0t0        TCP localhost:47813->localhost:9160 (ESTABLISHED)

This is a test node.js server, doing something very simple. (logging the request to Cassandra DB with the Helenus module)

I was surprised that there were so many open connections, when there definitely should be no more than a 1-2 connections at this moment.

Does this mean that I am I not ending my DB connections properly in the Node app? My code is below. Thanks.

var express = require('express')
 , routes = require('./routes')
 , app = express.createServer();


        app.configure(function(){
                        app.use(express.bodyParser());
                        app.use(express.methodOverride());
                        app.use(app.router);
                        });

        process.on('uncaughtException', function (err) {
                        logger.error('Caught exception: ' + err);
                        });

        function respond_test(req, res, next) {
                        var q = JSON.parse(req.query.q);
                        insert_db(q);
                        res.send('OK');
       }

       function insert_db(q) {
    var helenus = require('helenus'),
            pool = new helenus.ConnectionPool({
                 hosts      : ['localhost:9160'],
                    keyspace   : 'Test',
                    timeout    : 3000
        });

    pool.on('error', function(err){
                logger.error(err.name, err.message);
    });

           //makes a connection to the pool, this will return once there is at least one
           //valid connection, other connections may still be pending
           pool.connect(function(err, keyspace){
                        if(err){   throw(err);    }

                       keyspace.get('Test', function(err, cf){
                                        if(err){    throw(err);     }
                                        cf.insert(Date.now(), q, function(err){
                                                if(err){  throw(err);   }
                                       });
                         });
             });
    pool.close();
        }

        app.get('/test', respond_test);
       app.listen(80);

Upvotes: 1

Views: 2286

Answers (2)

Russ Bradberry
Russ Bradberry

Reputation: 10865

You are effectively connecting and disconnecting from cassandra on every request. The pool is designed to hold the connections open for you so you don't have to open and close constantly. This will greatly increase your performance as creating and destroying connections are expensive. I refactored your code a bit to give you an idea of how it is supposed to be used. I added some comments in there to help you out:

var express = require('express'),
    routes = require('./routes'),
    app = express.createServer(),
    //define cf in this scope to be set once connected
    test_cf;


function respond_test(req, res, next) {
  var q = JSON.parse(req.query.q);

  test_cf.insert(Date.now(), q, function(err){
    if(err){
      res.send('ERROR');
      throw(err);
    } else {
     res.send('OK');
    }
  });
}

var helenus = require('helenus'),
    pool = new helenus.ConnectionPool({
      hosts      : ['localhost:9160'],
      keyspace   : 'Test',
      timeout    : 3000
    });

app.configure(function(){
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
});

process.on('uncaughtException', function (err) {
  logger.error('Caught exception: ' + err);
});

pool.on('error', function(err){
  logger.error(err.name, err.message);
});

pool.connect(function(err, keyspace){
  if(err){
    throw(err);
  }

  keyspace.get('Test', function(err, cf){
    if(err){ throw(err); }
    test_cf = cf;
    //don't start listening until connected
    app.listen(80);
  });
});

app.on('close', function(){
  //close the pool if we stop listening on http
  pool.close();
});

app.get('/test', respond_test);

Upvotes: 2

Mustafa
Mustafa

Reputation: 10413

Because, in each operation you create a new pool. You are supposed to grab a connection from the pool, not create a new one each time, that's the advantage of the connection pool over regular. What a pool does is opening bunch of connections and then keeping them alive for future requests.

Upvotes: 1

Related Questions