AWS Lambda - кэширование MySQL - PullRequest
0 голосов
/ 01 марта 2019

У меня есть лямбда, которая использует RDS.Я хотел улучшить его и использовать кэширование Lambda-соединений.Я нашел несколько статей и реализовал их на моей стороне, насколько мне известно.Но теперь я не уверен, что это правильный путь.

У меня есть Lambda (работает на Node 8), в котором есть несколько файлов, используемых с require.Я начну с основной функции, пока не достигну инициализатора MySQL, который является точным путем.Все будет очень просто, показывая только поток кода, который работает MySQL:

Main 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);

MySQLBuilder:

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 до конца следующей недели ... И действительно, это было бы потрясающим началом выходных, зная, что я в правильном направлении... или нет.

Спасибо за ввод.

1 Ответ

0 голосов
/ 01 марта 2019

Прежде всего следует понять, как require работает в NodeJS.Я рекомендую вам пройти эту статью , если вы заинтересованы в том, чтобы узнать о ней больше.

Теперь, когда вам понадобится ваше соединение, оно у вас навсегда, и оно не будетпотребоваться снова.Это соответствует тому, что вы ищете, поскольку вы не хотите перегружать базу данных, каждый раз создавая новое соединение.

Но есть проблема ...

Лямбда-холодный запуск

Каждый раз, когда вы впервые вызываете лямбда-функцию, она раскручивает контейнер с вашей функцией внутри и поддерживает его в течение примерно 5 минут.Весьма вероятно (хотя и не гарантировано), что вы попадете в один и тот же контейнер каждый раз, пока вы делаете 1 запрос за раз.Но что произойдет, если у вас есть 2 запроса одновременно?Затем другой контейнер будет вращаться параллельно предыдущему, уже прогретому контейнеру.Вы только что создали другое соединение в вашей базе данных, и теперь у вас есть 2 контейнера.Теперь угадайте, что произойдет, если у вас есть 3 одновременных запроса?Да!Еще один контейнер, равный еще одному соединению с БД.

Пока есть новые запросы к вашим функциям Lambda, по умолчанию они будут масштабироваться для удовлетворения спроса (вы можете настроить его в консоли, чтобы ограничитьвыполнение столько одновременных исполнений, сколько вы хотите - с учетом ограничений вашей Учетной записи)

Вы не можете безопасно гарантировать, что у вас есть фиксированное количество подключений к вашей Базе данных, просто требуя ваш код для функциипризывание.Хорошо, что это не твоя вина.Именно так ведут себя лямбда-функции.

... еще один подход -

для кэширования данных, которые вы хотите в реальной системе кэширования, например ElasticCache, например.Затем вы можете запустить одну лямбда-функцию с помощью CloudWatch Event , которое выполняется с определенной частотой времени.Затем эта функция будет запрашивать вашу БД и сохранять результаты в вашем внешнем кеше.Таким образом, вы убедитесь, что ваше соединение с БД открывается только одной лямбда-сетью за раз, поскольку она будет учитывать событие CloudWatch, которое, как оказывается, запускается только один раз для каждого триггера.

РЕДАКТИРОВАТЬ : после того, как ОП отправил ссылку в разделах комментариев, я решил добавить еще немного информации, чтобы уточнить, что упомянутая статья хочет сказать

Отthe article:

"Simple. Вы можете хранить переменные вне области действия нашей функции-обработчика. Это означает, что вы можете создать свой пул соединений с БД вне функции-обработчика, которая затем можетпередаваться каждому последующему вызову этой функции. Это позволяет выполнять объединение. "

И это именно то, что вы делаете.И это работает!Но проблема в том, что если у вас N подключений (лямбда-запросов) одновременно.Если вы не установите никаких ограничений, по умолчанию до 1000 лямбда-функций могут быть запущены одновременно.Теперь, если вы сделаете еще 1000 запросов одновременно в течение следующих 5 минут, очень вероятно, что вы не будете открывать какие-либо новые подключения, поскольку они уже были открыты при предыдущих вызовах и контейнеры все еще живы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...