Как можно достичь лимита одновременного выполнения AWS Lambda? - PullRequest
0 голосов
/ 11 февраля 2019

ОБНОВЛЕНИЕ

Исходный тестовый код, приведенный ниже, в значительной степени корректен, но в NodeJS различные службы AWS должны быть настроены немного по-другому согласно предоставленной ссылке SDK by @ Michael-sqlbot

// manager
const AWS = require("aws-sdk")
const https = require('https');
const agent = new https.Agent({
    maxSockets: 498 // workers hit this level; expect plus 1 for the manager instance
});
const lambda = new AWS.Lambda({
    apiVersion: '2015-03-31',
    region: 'us-east-2', // Initial concurrency burst limit = 500
    httpOptions: {   // <--- replace the default of 50 (https) by
        agent: agent // <--- plugging the modified Agent into the service
    }
})
// NOW begin the manager handler code

Планируя новый сервис, я провожу предварительное стресс-тестирование.После прочтения о пределе 1000 одновременных выполнений на учетную запись и начальной скорости пакета (что в us-east-2 равно 500), я ожидал достичь как минимум 500 одновременных пакетовказни сразу.Скриншот ниже лямбда-метрики CloudWatch показывает обратное. Я не могу пройти 51 параллельное выполнение независимо от того, какое сочетание параметров я пытаюсь .Вот тестовый код:

// worker
exports.handler = async (event) => {
    // declare sleep promise
    const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

    // return after one second
    let nStart = new Date().getTime()
    await sleep(1000)
    return new Date().getTime() - nStart; // report the exact ms the sleep actually took
};

// manager
exports.handler = async(event) => {
    const invokeWorker = async() => {
        try {
            let lambda = new AWS.Lambda() // NO! DO NOT DO THIS, SEE UPDATE ABOVE
            var params = {
                FunctionName: "worker-function",
                InvocationType: "RequestResponse",
                LogType: "None"
            };
            return await lambda.invoke(params).promise()

        }
        catch (error) {
            console.log(error)
        }
    };

    try {
        let nStart = new Date().getTime()
        let aPromises = []

        // invoke workers
        for (var i = 1; i <= 3000; i++) {
            aPromises.push(invokeWorker())
        }

        // record time to complete spawning
        let nSpawnMs = new Date().getTime() - nStart

        // wait for the workers to ALL return
        let aResponses = await Promise.all(aPromises)

        // sum all the actual sleep times
        const reducer = (accumulator, response) => { return accumulator + parseInt(response.Payload) };
        let nTotalWorkMs = aResponses.reduce(reducer, 0)

        // show me
        let nTotalET = new Date().getTime() - nStart
        return {
            jobsCount: aResponses.length,
            spawnCompletionMs: nSpawnMs,
            spawnCompletionPct: `${Math.floor(nSpawnMs / nTotalET * 10000) / 100}%`,
            totalElapsedMs: nTotalET,
            totalWorkMs: nTotalWorkMs,
            parallelRatio: Math.floor(nTotalET / nTotalWorkMs * 1000) / 1000
        }
    }

    catch (error) {
        console.log(error)
    }
};

Response:
{
  "jobsCount": 3000,
  "spawnCompletionMs": 1879,
  "spawnCompletionPct": "2.91%",
  "totalElapsedMs": 64546,
  "totalWorkMs": 3004205,
  "parallelRatio": 0.021
}

Request ID:
"43f31584-238e-4af9-9c5d-95ccab22ae84"

Достигну ли я другого предела, который я не упомянул?Есть ли недостаток в моем тестовом коде?Я пытался достичь предела здесь с 3000 рабочих, но не произошло никакого регулирования, которое, я думаю, связано с асинхронным повторением вызова.

Редактировать : Естьнет ни одного VPC, задействованного ни в одной лямбде;настройка на выбранном входе «No VPC».

Edit : отображение Cloudwatch до и после исправления

Cannot exceed 51 Concurrent Executions With a fixed Agent, success is achieved

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Было несколько потенциальных подозреваемых, в частности, из-за того, что вы вызывали Lambda из Lambda, но ваш фокус на последовательном наблюдении параллелизма в 50 - кажущегося произвольным пределом (и подозрительно круглым числом) - напомнил мне, чтов JavaScript SDK есть скрывающая антиглуган:

В Node.js вы можете установить максимальное количество соединений на источник.Если установлен параметр maxSockets, низкоуровневый клиент HTTP ставит в очередь запросы и назначает их сокетам по мере их появления.

Здесь, конечно, «origin» означает любую уникальную комбинацию схемы + имени хоста, которая вв данном случае это служба конечная точка для лямбды в us-east-2, к которой подключается SDK для вызова метода Invoke, https://lambda.us-east-2.amazonaws.com.

Thisпозволяет установить верхнюю границу количества одновременных запросов к данному источнику за раз.Понижение этого значения может уменьшить количество полученных ошибок регулирования или тайм-аута.Однако это также может увеличить использование памяти, поскольку запросы помещаются в очередь до тех пор, пока сокет не станет доступным.

...

При использовании по умолчанию https SDK принимает значение maxSocketsот globalAgent.Если значение maxSockets не определено или равно бесконечности, SDK принимает значение maxSockets, равное 50.

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/node-configuring-maxsockets.html

0 голосов
/ 11 февраля 2019

Лямбда-параллелизм - не единственный фактор, который определяет масштабируемость ваших функций.Если ваша лямбда-функция выполняется в пределах VPC, ей потребуется ENI (Elastic Network Interface), который разрешает сетевой трафик от и к контейнеру (лямбда-функция).

Возможно, ваше удушение произошло из-за слишком большого количестваENI запрашивается (50 одновременно).Вы можете проверить это, просмотрев журналы лямбда-функции Manager и посмотрев сообщение об ошибке при попытке вызвать один из дочерних контейнеров.Если ошибка выглядит следующим образом, вы знаете, что проблема в ENI.

Lambda was not able to create an ENI in the VPC of the Lambda function because the limit for Network Interfaces has been reached.

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