Connection Pooling in AWS Lambda with RDS?
Asked Answered
P

2

5

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");
        }
    });
};
Paisley answered 17/1, 2018 at 9:33 Comment(1)
Can you please share the use case for the same?Artless
W
5

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.

Woodwind answered 17/1, 2018 at 14:8 Comment(0)
R
1

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/

Ribbon answered 26/4, 2019 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.