gpt4 book ai didi

node.js - 在亚马逊 lambda 上使用 mysql 池

转载 作者:搜寻专家 更新时间:2023-10-31 23:31:16 25 4
gpt4 key购买 nike

我正在尝试在 Amazon Lambda 上运行的 NodeJS 服务中使用 mysql 池。这是我使用数据库的模块的开头:

console.log('init database module ...');
var settings = require('./settings.json');
var mysql = require('mysql');
var pool = mysql.createPool(settings);

从亚马逊控制台的日志中可以看出,这段代码被执行得非常频繁:

  1. 如果我刚刚部署了服务并同时执行了 10 个请求 - 所有这 10 个请求都执行了这段代码。
  2. 如果我在第一个系列之后立即再次同时执行 10 个请求 - 它们不会执行此代码。
  3. 如果从上次查询开始过去了一些时间 - 那么一些请求会重新执行该代码。

即使我使用 global - 这会减少但不会消除重复项:

if (!global.pool) {
console.log('init database module ...');
var settings = require('./settings.json');
var mysql = require('mysql');
global.pool = mysql.createPool(settings);
}

此外,如果请求执行有一些错误 - 这段代码在请求之后执行,此时 global.pool 为空。

那么,这是否意味着无法在 Amazon Lambda 中使用池?是否有任何选项可以让亚马逊每次都使用相同的池实例?

最佳答案

每次调用 Lambda 函数时,它都会在自己独立的容器中运行。如果没有可用的空闲容器,服务会自动创建一个新容器。因此:

  1. If I just deployed the service and executed 10 requests simultaneously - all these 10 requests execute this piece of code.

如果容器可用,它可能并且很可能会被重复使用。当发生这种情况时,进程已经在运行,因此全局部分不会再次运行——调用从处理程序开始。因此:

  1. If I again execute 10 requests simultaneously immediately after first series - they don't execute this code.

每次调用完成后,使用过的容器将被卡住,最终将被解冻并重新用于后续调用,或者如果几分钟后不需要它,则将其销毁。因此:

  1. If some time is passed from last query - then some of the requests re-execute that code.

现在说得通了,对吧?

唯一的“陷阱”是容器被销毁之前必须耗时量不是固定值。有趣的是,它似乎是大约 15 分钟,但我不相信它被记录在案,因为计时器很可能是自适应的......服务可以(自行决定)使用试探法来预测最近的事件是否是峰值或可能持续,可能还要考虑其他因素。

(Lambda@Edge 是与 CloudFront 集成用于 HTTP header 操作的 Lambda,它似乎以不同的时间运行。空闲容器似乎持续时间更长,至少数量很少,但这是有道理的,因为它们总是非常小容器......而且这个观察再次是轶事。)

代码的全局部分仅在创建新容器时运行。

池化没有意义,因为在调用期间没有共享任何内容——每次调用都是唯一在其容器中运行的调用——每个进程一个——在任何时候。

不过,您需要做的是更改连接上的 idle_timeout。 MySQL Server 没有有效的方法来“发现”空闲连接已完全消失,因此当容器被销毁时连接消失,服务器只是坐在那里,连接保持在 Sleep 状态,直到默认的 idle_timeout 到期。默认值为 28800 秒或 8 小时,这太长了。您可以在服务器上更改它,或发送查询 SET @@IDLE_TIMEOUT = 900(尽管您需要尝试使用适当的值)。

或者,您可以在每次调用的处理程序内建立和销毁连接。当然,这会花费更多时间,但如果您的函数不会经常运行,这是一种明智的方法。 MySQL 客户端/服务器协议(protocol)的连接/握手序列是相当轻量级的,频繁的连接/断开连接不会像您预期的那样给服务器带来那么多的负载……尽管您不想在使用的 RDS 服务器上这样做IAM token 身份验证,这更耗费资源。

关于node.js - 在亚马逊 lambda 上使用 mysql 池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46138616/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com