【问题标题】:Using mysql pool on amazon lambda在亚马逊 lambda 上使用 mysql 池
【发布时间】:2017-09-10 08:09:03
【问题描述】:

我正在尝试在我在 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 中使用池? 有什么办法可以让亚马逊每次都使用同一个池实例吗?

【问题讨论】:

  • 您在第 1、2 和 3 点中描述的所有内容都与 Lambda 中的多个容器和 container reuse 一致。你熟悉这个吗?
  • 结论是什么?池化没有意义,对吧?
  • 虽然没有提供池的全部好处,但您可以在处理函数之外使用 mysql.createPool() 并在完成后使用 connection.destroy()。见stackoverflow.com/questions/14087924/…

标签: node.js aws-lambda


【解决方案1】:

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

  1. 如果我刚刚部署服务并同时执行 10 个请求 - 所有这 10 个请求都会执行这段代码。

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

  1. 如果我在第一个系列之后立即再次同时执行 10 个请求 - 它们不会执行此代码。

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

  1. 如果从上次查询过去了一段时间 - 一些请​​求会重新执行该代码。

现在说得通了,对吧?

唯一的“问题”是容器被销毁之前必须经过的时间量不是一个固定值。有趣的是,它似乎大约是 15 分钟,但我不相信它被记录在案,因为计时器很可能是自适应的......服务可以(根据自己的决定)使用启发式方法来预测最近的活动是峰值还是可能持续,并且可能考虑其他因素。

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 2012-12-08
    相关资源
    最近更新 更多