AWS Lambda和数据库

4

我一直在理论上学习,创建新的数据库连接是一项昂贵的操作。因此,我们应该保持开放的连接池,并将其用于数据库操作。

考虑到 AWS Lambda。假设 Lambda 函数想要操作数据库,那么我们需要创建一个与数据库的连接。操作完成后,需要关闭数据库。如果同时有数百个 Lambda 函数正在执行,则会进行数百次数据库连接的打开/关闭操作。这在理论上是一种不好的模式。

如果是这样,那么在涉及数据库操作时使用 AWS Lambda 是否不合适?

2个回答

4
为什么需要在Lambda函数中关闭DB连接并不重用它?
每个Lambda函数的运行都意味着一个容器,它们在运行后会保持一段时间的存活状态(几十分钟),如果您连续调用它,它将保持存活状态。
存活意味着每个Lambda函数在运行后保留内存区域,以便可以重复使用它们。
例如,如果您在Lambda函数中定义全局变量,如下所示。 (虽然这是Python代码,但我认为您可以理解,因为它足够简单)
variable = 10

def lambda_function(event, context):
    global variable
    print(variable)  
    variable += 1

如果Lambda函数每秒被调用一次,它将会像下面这样打印输出。
10
11
12
13
14
.
.
.

正如您所看到的,每个调用的Lambda函数都使用相同的全局变量。如果全局变量是DB连接,您可以重复使用它们而不必在每个lambda调用时重新打开连接。
然而,正如您所说,如果同时执行100个Lambda函数,则会打开100个连接,因为每个Lambda并发意味着具有不同内存区域的不同容器。
但最终,100个连接将被用于顺序的100个同时执行。
---------- 编辑 ----------
我同意@Arun的评论。我的答案将在流量稳定增长和逐渐减少的情况下有用,这样连接就足够被重复使用,并由服务器端的保持活动状态关闭。流量的急剧增加和减少可能会浪费没有适当关闭的DB连接。
---------- 编辑 ---------- 2019-12-17
AWS宣布了新功能RDS代理,尽管它仍处于预览阶段。如果通过RDS代理连接RDS,则它将为您管理DB连接池(Lambda <-> RDS)。

详细信息,请参考此链接


1
我对你的回答并不完全满意。在Lambda中使用全局变量进行数据库连接,如果Lambda非常活跃(即Lambda不断接收请求),并且不关闭它,那么这种方法是可行的。但是,在Lambda仅在某个时间段内接收请求而在之后不再接收请求的情况下(例如,另外5或10分钟内没有请求),容器将开始排空,而连接未被正确关闭。如果同时,用户尝试访问Lambda,则会尝试创建新容器,并可能无法找到适当数量的连接可用性。 - Arun

1

连接池在无服务器环境下正常工作。

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"
    });
         })
}

我认为问题被误解了。创建连接池肯定是有效的。但问题在于当Lambda进程被终止时,连接池没有被正确关闭。另一个问题是在自动缩放期间会创建数百个连接池,这可能会耗尽最大连接限制。 - Pavan Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接