Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connection Pooling in AWS Lambda with RDS?

I need effective MySQL database connection in AWS Lambda (Using Node Js).

Which is not creating connection/pool for every request, instead reuse it.

One Solution I got like opening connection outside AWS lambda handler. But the problem with this case if we not end the connection, we end up with timeout result. e.g.

"use strict";
var db = require('./db');
exports.handler = (event, context, callback) => {
    db.connect(function (conn) {
        if (conn == null) {
            console.log("Database connection failed: ");
            callback("Error", "Database connection failed");
        } else {
            console.log('Connected to database.');
            conn.query("INSERT INTO employee(name,salary) VALUE(?,?)",['Joe',8000], function(err,res){
                if(err) throw err;
                else {
                    console.log('A new employee has been added.');
                }
            });
            db.getConnection().end();
            callback(null, "Database connection done");
        }
    });
};
like image 463
Swapnil Kadu Avatar asked Oct 17 '22 00:10

Swapnil Kadu


2 Answers

The most reliable way of handling database connections in AWS Lambda is to connect and disconnect from the database within the invocation itself which is what your code is already doing.

There are known ways to reuse an existing connection but success rates for that vary widely depending on database server configuration (idle connections, etc.) and production load.

Also, in the context of AWS Lambda, reusing database connections does not give you as much performance benefit due to the way how scaling works in Lambda.

In an always-on server app for example, concurrent and succeeding requests use and share the same connection or connection pool.

In Lambda however, concurrent requests are handled by different servers, with each of them having their own connection to the database. 10 concurrent requests will spin 10 separate servers connecting to your database. Reusing connections or connection pools won't be of any help here.

like image 194
Noel Llevares Avatar answered Oct 30 '22 14:10

Noel Llevares


To solve your problem, use:

context.callbackWaitsForEmptyEventLoop = false;

The reason a timeout is happening is because the event loop is not empty as a result of the code outside of the handler. This change allows to callback to immediately end the lambda's execution. Your full code would look something like this:

var db = require('./db');
exports.handler = (event, context, callback) => {

    context.callbackWaitsForEmptyEventLoop = false;

    db.connect(function (conn) {
       // .. rest of your code that calls the callback
    });
}

For more information, check this the blog post by Jeremy Daly.

https://www.jeremydaly.com/reuse-database-connections-aws-lambda/

like image 39
Michael Oosthuizen Avatar answered Oct 30 '22 12:10

Michael Oosthuizen