Mysql 我应该在AWS Lambda中使用连接池吗?
我最近用lambda将一个API从EC2实例切换到API网关。我注意到我在数据库上的CPU使用率迅速上升 下面是数据库上活动连接的图像,红色箭头是我从EC2切换到Lambda时显示的。没有新增客户,因此数据的实际吞吐量保持不变 我使用的代码与我在Ec2实例上托管时使用的代码相同。这段代码使用一个连接池来连接数据库,我不确定这是不是最好的主意。基本上,当我想在主脚本中查询数据库时,我调用Mysql 我应该在AWS Lambda中使用连接池吗?,mysql,amazon-web-services,aws-lambda,aws-api-gateway,aws-serverless,Mysql,Amazon Web Services,Aws Lambda,Aws Api Gateway,Aws Serverless,我最近用lambda将一个API从EC2实例切换到API网关。我注意到我在数据库上的CPU使用率迅速上升 下面是数据库上活动连接的图像,红色箭头是我从EC2切换到Lambda时显示的。没有新增客户,因此数据的实际吞吐量保持不变 我使用的代码与我在Ec2实例上托管时使用的代码相同。这段代码使用一个连接池来连接数据库,我不确定这是不是最好的主意。基本上,当我想在主脚本中查询数据库时,我调用query方法 从连接池中检索连接,以便lambda函数运行查询,然后在查询结束时释放连接 这是一种好方法,还
query
方法
从连接池中检索连接,以便lambda函数运行查询,然后在查询结束时释放连接
这是一种好方法,还是应该在lambda函数的整个执行过程中始终保持一个连接?自从我搬到Lambda后,T3媒体上的CPU使用率几乎达到了极限,我认为这就是问题所在
// This file is used to get a connection from the mysql connection pool
// The pool is contained in this file and the function to get a connection is exported
// Imports //
const mysql = require('mysql')
// Define the connection pool //
const pool = mysql.createPool({
host: process.env.DBHOST,
user: process.env.DBUSER,
password: process.env.DBPASSWORD,
port: process.env.DBPORT,
database: process.env.DBNAME
})
/// getConnection ///
// Call this function whereever you need a connection
// It gets a connection from the connection pool
function getConnection(){
return new Promise((resolve,reject) => {
pool.getConnection((err,con) => {
if(err){
reject(`Connection Failed\n${err}`);
}else{
console.info(`Successful connection, id ${con.threadId}`)
resolve(con)
}
})
})
}
/// query ///
// This function makes a query on a database
// It accepts and sql statement and a list of args if used in the statemens
// Inputs:
// sql - The sql statement to execute on the database
// args - The arguments to use in the sql statament
// Returns:
// resolve - The result of the sql insert statemen
// reject - An error
async function query(sql,args){
return new Promise(async(resolve,reject) => {
// try/catch is to handle the await for the connection
try{
let con = await getConnection() // If there is an error here it will be caught
// No error this query will execute
con.query(sql,args, function(err,result) {
// If error returned from query will be caught here
if (err){
reject(err);// Reject the promise
}else{
resolve(result);// Resolve the promise
}
// Always release
con.release()
})
}catch(error){
// Error in getting connection reject the error
reject(error)
}
})
}
module.exports = {query}
最大的区别可能是,与单个实例相比,您的lambda worker可能并行运行得更多,并且/或者lambda worker必须始终连接和断开连接。如果需要连接池,则需要将其作为lambda和数据库之间的单独实例,因为单个lambda实例无法在内部共享连接池之类的资源。我想说,使用率高达50%的峰值似乎可以更有效地使用可用的数据库资源。不过,你应该注意不要让它增加太多。与单个实例相比,您的API响应时间或处理时间是否同时提高了…?是的,同样,即使您在Lambda worker内部共享连接,几个并行Lambda worker仍将创建许多到数据库的连接。您将需要考虑LAMBDA工作者和数据库之间的连接池,以减少数据库应力,和/或限制您的lambda并发性。我还不必使用RDS代理,但当然,它覆盖了最大的并行连接,并通过最大并行运行查询,因此当然应该限制CPU使用率。这还意味着您的Lambda工作人员可能会在等待连接/游标可用时进行一些备份,这最终会限制您可以并行处理的请求数量。您需要找出自己的具体瓶颈,并根据需要进行调整。