mysql - AWS Lambda - MySQL 缓存

标签 mysql node.js aws-lambda

我有使用 RDS 的 Lambda。我想改进它并使用 Lambda 连接缓存。据我所知,我已经找到了几篇文章,并在我这边实现了它。但是现在,我不确定这是不是正确的方法。

我有 Lambda(运行 Node 8),它有几个与 require 一起使用的文件。我将从 main 函数开始,直到到达 MySQL 初始化程序,这是确切的路径。一切都将非常简单,仅显示运行 MySQL 的代码流:

主要 Lambda:

const jobLoader = require('./Helpers/JobLoader');

exports.handler = async (event, context) => {
    const emarsysPayload = event.Records[0];
    let validationSchema;

    const body = jobLoader.loadJob('JobName');
     ...
    return;
...//

工作代码:

const MySQLQueryBuilder = require('../Helpers/MySqlQueryBuilder');

exports.runJob = async (params) => {
      const data = await MySQLQueryBuilder.getBasicUserData(userId);

MySQL构建器:

const mySqlConnector = require('../Storage/MySqlConnector');

    class MySqlQueryBuilder {
        async getBasicUserData (id) {
            let query = `
    SELECT * from sometable WHERE id= ${id} 
    `;

            return mySqlConnector.runQuery(query);
        }
    }

最后是连接器本身:

const mySqlConnector = require('promise-mysql');
const pool = mySqlConnector.createPool({
        host: process.env.MY_SQL_HOST,
        user: process.env.MY_SQL_USER,
        password: process.env.MY_SQL_PASSWORD,
        database: process.env.MY_SQL_DATABASE,
        port: 3306
    });

    exports.runQuery = async query => {
        const con = await pool.getConnection();
        const result = con.query(query);
        con.release();
        return result;
    };

我知道衡量性能会显示实际结果,但今天是星期五,我要到下周晚些时候才能在 Lambda 上运行它……真的,如果知道这将是一个很棒的周末开始我在正确的方向......或不是。

感谢您的投入。

最佳答案

首先要了解 require 在 NodeJS 中是如何工作的。我建议你通过这个 article如果您有兴趣了解更多。

现在,一旦您需要连接,您就永远拥有它,并且不会再次需要它。这符合您正在寻找的内容,因为您不希望每次都创建一个新连接而使数据库不堪重负。

但是,有个问题...

Lambda 冷启动

每当您第一次调用 Lambda 函数时,它都会启动一个容器,其中包含您的函数,并使其保持事件状态大约 5 分钟。只要您一次发出 1 个请求,您很可能(尽管不能保证)每次都会访问同一个容器。但是如果你同时有 2 个请求会发生什么?然后另一个容器将与之前已经预热的容器并行旋转。您刚刚在数据库上创建了另一个连接,现在您有 2 个容器。现在,猜猜如果您有 3 个并发请求会发生什么情况?是的!多一个容器,等于多一个数据库连接。

只要有对您的 Lambda 函数的新请求,默认情况下,它们就会扩展以满足需求(您可以在控制台中配置它以将执行限制为您想要的任意数量的并发执行 - 尊重您的账户限制)

您不能通过在函数调用时简单地要求您的代码来安全地确保您有固定数量的数据库连接。好在这不是你的错。这就是 Lambda 函数的行为方式。

...另一种方法是

在真正的缓存系统中缓存你想要的数据,比如ElasticCache , 例如。然后,您可以让 CloudWatch Event 触发一个 Lambda 函数以一定的时间频率运行。然后此函数将查询您的数据库并将结果存储在外部缓存中。通过这种方式,您可以确保您的数据库连接一次仅由一个 Lambda 打开,因为它会遵守 CloudWatch 事件,结果证明每个触发器只运行一次。

编辑:在 OP 在评论部分发送链接后,我决定添加更多信息以阐明上述文章想要表达的内容

来自文章:

"Simple. You ARE able to store variables outside the scope of our handler function. This means that you are able to create your DB connection pool outside of the handler function, which can then be shared with each future invocation of that function. This allows for pooling to occur."

而这正是您正在做的。这有效!但问题是如果你同时有 N 个连接(Lambda 请求)。如果您不设置任何限制,默认情况下最多可以同时启动 1000 个 Lambda 函数。现在,如果您在接下来的 5 分钟内同时发出另外 1000 个请求,您很可能不会打开任何新连接,因为它们已经在之前的调用中打开并且容器仍然存在。

关于mysql - AWS Lambda - MySQL 缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54947095/

相关文章:

java - 如何使用 json 从 mysql 检索图像?

mysql - NestJS/TypeORM。 TypeORM 不更新数据库中的实体,而是使用旧的缓存实体

mysql - SQL 非负数和 TinyInt 问题

javascript - ExpressJS 设置/获取/使用 cookie

go - 如何使用 golang 为 lambda 函数提供配置值

mysql - 如何处理查询字符串 Node Js AWS Lambda

php - User agent header - mysql存储的缩写

node.js - 用于 webstorm 的 Sass 文件观察器

javascript - 在 URL 浏览器字段中输入子 URL 时不显示路由

amazon-web-services - 如何使用 OpenAPI 为 AWS API Gateway 配置 CORS?