AWS lambda 和数据库
AWS lambda and Database
我一直在理论上了解到,创建与数据库的新连接是一项代价高昂的操作。所以我们应该保持打开连接池并将其用于数据库操作。
考虑 AWS lambda 时。假设 lambda 函数要对 db 进行操作,那么我们需要创建一个到 db 的连接。操作完成后,需要关闭db。如果同时执行 100 个 lambda 函数,那么将完成 100 个数据库连接 open/close。这在理论上是错误的模式。
如果是这样,那么在涉及数据库操作时使用 AWS lambda 是否不合适?
连接池在 Serverless 上运行良好
即
const mysql = require('mysql');
const pool = mysql.createPool({
host: {Your Host},
user: {Your Username},
password: {Your Password},
database: {Your Database},
port: 3306
});
exports.main = function main (req) {
let query = ""
return new Promise(function(resolve, reject){
return resolve({
statusCode: 200,
body: "Success"
});
})
}
为什么需要关闭 DB
连接,而不是在 Lambda
函数中重新使用它?
每个Lambda
函数运行表示一个Container
并且它们会在运行之后存活一段时间(几个10分钟,如果你连续调用它,它会一直活着)。
活着意味着每个Lambda
函数在运行之后保留内存区域,以便它可以重用它们。
例如,如果您在 Lambda
函数中定义一个全局变量,如下所示。
(虽然是python代码,但我想你可以理解,因为它已经足够简单了)
variable = 10
def lambda_function(event, context):
global variable
print(variable)
variable += 1
如果每 1 秒调用一次 Lambda
函数,它将打印如下。
10
11
12
13
14
.
.
.
如您所见,调用的每个 Lambda
函数都使用相同的全局变量。
如果全局变量是DB连接怎么办?您可以重复使用它们,而不是在每次 lambda 调用时都重新打开连接。
但是,如你所说,如果同时执行100个Lambda
函数,将打开100个连接,因为每个Lambda
并发意味着不同的Containers
,具有不同的内存区域。
但最后,100 个连接将被重复用于顺序 100 个同时执行。
------------编辑---------
我同意 @Arun
的评论。当流量稳定并且逐渐增加和减少时,我的回答将很有用,这样连接就可以被足够重用并通过服务器端的保持连接关闭。流量的急剧增加和减少可能会浪费数据库连接而不正确关闭。
------------编辑-------- 2019-12-17
AWS 宣布了新功能 RDS proxy
,尽管它还处于预览阶段。
如果您通过 RDS proxy
连接 RDS,它将为您管理数据库连接池(Lambda <-> RDS)。
有关详细信息,请参考此 link
我一直在理论上了解到,创建与数据库的新连接是一项代价高昂的操作。所以我们应该保持打开连接池并将其用于数据库操作。
考虑 AWS lambda 时。假设 lambda 函数要对 db 进行操作,那么我们需要创建一个到 db 的连接。操作完成后,需要关闭db。如果同时执行 100 个 lambda 函数,那么将完成 100 个数据库连接 open/close。这在理论上是错误的模式。
如果是这样,那么在涉及数据库操作时使用 AWS lambda 是否不合适?
连接池在 Serverless 上运行良好 即
const mysql = require('mysql');
const pool = mysql.createPool({
host: {Your Host},
user: {Your Username},
password: {Your Password},
database: {Your Database},
port: 3306
});
exports.main = function main (req) {
let query = ""
return new Promise(function(resolve, reject){
return resolve({
statusCode: 200,
body: "Success"
});
})
}
为什么需要关闭 DB
连接,而不是在 Lambda
函数中重新使用它?
每个Lambda
函数运行表示一个Container
并且它们会在运行之后存活一段时间(几个10分钟,如果你连续调用它,它会一直活着)。
活着意味着每个Lambda
函数在运行之后保留内存区域,以便它可以重用它们。
例如,如果您在 Lambda
函数中定义一个全局变量,如下所示。
(虽然是python代码,但我想你可以理解,因为它已经足够简单了)
variable = 10
def lambda_function(event, context):
global variable
print(variable)
variable += 1
如果每 1 秒调用一次 Lambda
函数,它将打印如下。
10
11
12
13
14
.
.
.
如您所见,调用的每个 Lambda
函数都使用相同的全局变量。
如果全局变量是DB连接怎么办?您可以重复使用它们,而不是在每次 lambda 调用时都重新打开连接。
但是,如你所说,如果同时执行100个Lambda
函数,将打开100个连接,因为每个Lambda
并发意味着不同的Containers
,具有不同的内存区域。
但最后,100 个连接将被重复用于顺序 100 个同时执行。
------------编辑---------
我同意 @Arun
的评论。当流量稳定并且逐渐增加和减少时,我的回答将很有用,这样连接就可以被足够重用并通过服务器端的保持连接关闭。流量的急剧增加和减少可能会浪费数据库连接而不正确关闭。
------------编辑-------- 2019-12-17
AWS 宣布了新功能 RDS proxy
,尽管它还处于预览阶段。
如果您通过 RDS proxy
连接 RDS,它将为您管理数据库连接池(Lambda <-> RDS)。
有关详细信息,请参考此 link