为什么并发 AWS Lambda(在 VPC 内)执行没有抱怨 VPC 中的 IP 限制?

Why concurrent AWS Lambda (inside VPC) execution is not complaining about IP limit in VPC?

我们在 AWS lambda 上进行了快速实验,以根据我们的 VPC IP 限制确认并发执行限制?在我们的 AWS 账户中,VPC 有大约 500 个 IP 可用。一般来说,如果 AWS lambda 运行ning 在 VPC 内,如果并发 lambda 运行ning 多于可用 IP,则可用 IP 可能会耗尽。下面是实验细节和 Lambda 函数。

我们编写了一个 lambda 调用程序(参考下面的#1)函数,它调用在 VPC 中配置的 lambda 调用函数(参考#2)。我们调用了一个名为 function 的 lambda 大约 999 次,并确保所有这些都应该 运行 同时发生。但令人惊讶的是,所有 lambda 都毫无怨言地完成了。

最大的问题是,如果我们的 VPC 中有 500 个 IP 限制并且我们在 VPC 中 运行 lambda 999 次,为什么我们没有得到 IP 可用性问题?有什么想法吗?

1. Lambda 调用函数 (Node.js 10.x)

const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();

const duration = 3 * 60 * 1000;

exports.handler = async (event) => {

    try {

        const lambdaPosterParams = {
            FunctionName: 'testCalledFunction',
            InvocationType: 'Event',
            LogType: 'None'
        };

        for (var invokationNumber=0; invokationNumber<999; invokationNumber++) {
            console.log("Invoking lambda #" + invokationNumber);
            lambdaPosterParams.Payload = JSON.stringify({
                'invokationNumber': invokationNumber,
                'duration': duration,
                'tableName': 'testload2'
            });
            const posterResponse = await lambda.invoke(lambdaPosterParams).promise();
            console.log("Poster Lambda invoked", JSON.stringify(posterResponse));
        }
    } catch (error){
        console.error('Error invoking lambda #' + invokationNumber, error);
        throw error;

    }
    console.log("All lambdas invoked");
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};

2。 Lambda 调用函数 (Node.js 10.x)

const AWS = require('aws-sdk');

const dbConnection = new AWS.DynamoDB({region: process.env.AWS_REGION, apiVersion: process.env.AWS_DYNAMODB_API_VERSION});

exports.handler = async (event) => {

    const startTime = new Date();
    const insertData = {
        'TableName': 'testload',
        'Item': {
            'invokationNumber': {'N': event.invokationNumber.toString()},
            'startTime': {'S': startTime.toUTCString()},
        }
    };

    await dbConnection.putItem(insertData).promise();


    console.log(`Event #${event.invokationNumber}. Sleeping...`);

    await timeout(3 * 60 * 1000);

    console.log('Waking up...');

    const endTime = new Date();
    insertData.Item.endTime = {'S': endTime.toUTCString()};
    insertData.Item.duration = {'N': (endTime.getTime() - startTime.getTime()).toString()};

    await dbConnection.putItem(insertData).promise();

    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };

    return response;

    function timeout(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
};

每次并发调用级别为 1 时不需要 ENI,除非您的函数配置为每次调用分配最大允许的 3 GB 内存。

在 1.5 GB 时,您可以有两个并发调用,在 1 GB 时是三个,在 512 MB 时是六个,在 128 MB 时大约是 24 个并发调用每个弹性网络接口( ENI).

大约。

这是因为您的容器分配在 m-class 个 EC2 实例(或非常相似的实例)上,每个 个实例 个 ENI,并且每个实例有 3 GB 的可用空间容器可用的内存。分配给函数的内存越小,每个(隐藏的、托管的)EC2 实例的容器越多,因此给定的并发级别所需的 ENI 越少。

If your Lambda function accesses a VPC, you must make sure that your VPC has sufficient ENI capacity to support the scale requirements of your Lambda function. You can use the following formula to approximately determine the ENI requirements.

Projected peak concurrent executions * (Memory in GB / 3GB)

https://docs.aws.amazon.com/lambda/latest/dg/vpc.html

将您的函数配置为 3 GB,您最初的期望应该得到确认——您将 运行 没有 ENI,这可能是由于缺少 IP 地址,或者您的帐户限制了最大数量该地区的 ENI。