Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 我应该在AWS Lambda中使用连接池吗?_Mysql_Amazon Web Services_Aws Lambda_Aws Api Gateway_Aws Serverless - Fatal编程技术网

Mysql 我应该在AWS Lambda中使用连接池吗?

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函数运行查询,然后在查询结束时释放连接 这是一种好方法,还

我最近用lambda将一个API从EC2实例切换到API网关。我注意到我在数据库上的CPU使用率迅速上升

下面是数据库上活动连接的图像,红色箭头是我从EC2切换到Lambda时显示的。没有新增客户,因此数据的实际吞吐量保持不变

我使用的代码与我在Ec2实例上托管时使用的代码相同。这段代码使用一个连接池来连接数据库,我不确定这是不是最好的主意。基本上,当我想在主脚本中查询数据库时,我调用
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工作人员可能会在等待连接/游标可用时进行一些备份,这最终会限制您可以并行处理的请求数量。您需要找出自己的具体瓶颈,并根据需要进行调整。