Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Lambda RDS too many connections

I have connected an AWS Lambda function to Amazon RDS (MySQL). When the Lambda function is invoked 100 times simultaneously, there are almost 400 connections opened in RDS (as shown in RDS console). Why is this?

I checked the active connections using:

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE DB = "MYDB";

All the connections are from Lambda containers. Does anyone know how Lambda containers act on simultaneous requests? Why are the containers not reused?

Current Configuration:

var sequelize = new Sequelize('DB','username', 'password' ,{ dialect: 'mysql', port: port, host: host, pool: { max: 20, min: 0, idle: 300000 } });

Even if one connection is opened per request it should be 100. How 400 connections are opened?

I'm using Sequelize. Node JS 6.9.1

Note: Connection Happens only once outside Lambda Handler method

like image 377
Viswanath Lekshmanan Avatar asked Jul 21 '17 06:07

Viswanath Lekshmanan


3 Answers

AWS "new" solution for this problem seems to be RDS Proxy: https://aws.amazon.com/de/rds/proxy/

RDS Proxy establishes and manages the necessary connection pools to your database so that your application creates fewer database connections.

You can use RDS Proxy for any application that makes SQL calls to your database. But in the context of serverless, we focus on how this improves the Lambda experience.

https://aws.amazon.com/de/blogs/compute/using-amazon-rds-proxy-with-aws-lambda/

like image 96
MarkR Avatar answered Nov 19 '22 10:11

MarkR


Sequelize by defaults creates a connection pool, so it's creating 4 connections because it's designed to run as a long running service. You can disable this by setting options.pool to false see the API reference

However as your application scales this is a fundamental problem with Lambda that won't go away. I recommend building a DB proxy layer in EC2 to terminate your db connections (i.e. using ProxySQL). It will then have a connection pool to the rds db.

The only way around this is to use dynamodb as your backend store.

like image 20
Robo Avatar answered Nov 19 '22 12:11

Robo


The lambda can have many concurrent executions. So, more than one connection can be through by the lambda.

To fix this you need to change sequelize:

var sequelize = new Sequelize('DB','username', 'password' ,{
  dialect: 'mysql',
  port: port,
  host: host,
  pool: {
    max: 1,
    min: 1,
    idle: 15000
  }
});

Keep the pool with only one connection, in this way the connection will be reused on the next execution and remember to dont close connection after the lambda execution.

Read this article about to reuse database connection on next executions.

like image 1
Yuri Giovani Avatar answered Nov 19 '22 11:11

Yuri Giovani