Медленная инициализация клиента S3 в AWS Lambda - PullRequest
0 голосов
/ 28 апреля 2018

В настоящее время я работаю над лямбда-функцией AWS, написанной на Java. Ему нужно выбрать объекты из S3, и поэтому я настроил роль IAM и собираю клиента S3 в обработчике Lambda:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

public class Example implements RequestHandler<Void, Void> {

    @Override
    public Void handleRequest(Void nothing, Context ctx) {
        long start = System.currentTimeMillis();
        AmazonS3 amazonS3 = AmazonS3ClientBuilder.defaultClient();
        ctx.getLogger().log("Creating S3 client took " + (System.currentTimeMillis() - start) + "ms");
        ...
        return null;
    }
}

Тем не менее, использование AmazonS3ClientBuilder очень медленно, оператор log выводит следующие моменты времени при выделении функции 192 МБ:

Creating S3 client took 13541ms
Creating S3 client took 16482ms
Creating S3 client took 13617ms
Creating S3 client took 16380ms

Даже при увеличении памяти до 3008 МБ для получения максимальной вычислительной мощности (поскольку AWS распределяет мощность процессора пропорционально памяти для Lambdas), клиенту все равно требуется от 1 до 2 секунд:

Creating S3 client took 1413ms
Creating S3 client took 1170ms
Creating S3 client took 1528ms
Creating S3 client took 1394ms

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

Неправильно ли я использую AmazonS3ClientBuilder, возможно, не переопределяя некоторые значения по умолчанию, что приводит к снижению производительности? Как ускорить инициализацию клиента?

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

Клиенты AWS считаются поточно-ориентированными и могут безопасно использоваться несколькими запросами одновременно. Вы должны иметь возможность создавать клиента как переменную-член и повторно использовать один и тот же клиент для каждого запроса. Это должно сэкономить значительное время, так как клиент по умолчанию делает несколько вызовов aws каждый раз, когда он создается для поиска региона и учетных данных.

0 голосов
/ 11 декабря 2018

AWS SDK для Java 2.0 был выпущен в ноябре. Это в основном переписанная версия 1.x и, похоже, она немного улучшила производительность. Миграция кода из вопроса об использовании нового SDK даст нам что-то похожее на следующее:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import software.amazon.awssdk.services.s3.S3Client;

public class Example implements RequestHandler<Void, Void> {

    @Override
    public Void handleRequest(Void nothing, Context ctx) {
        long start = System.currentTimeMillis();
        S3Client s3Client= S3Client.create();
        ctx.getLogger().log("Creating S3 client took " + (System.currentTimeMillis() - start) + "ms");
        ...
        return null;
    }
}

При выделении функции 192 МБ:

Creating S3 client took 9380ms
Creating S3 client took 9719ms
Creating S3 client took 10098ms
Creating S3 client took 9519ms

При выделении 3008 МБ функции:

Creating S3 client took 884ms
Creating S3 client took 873ms
Creating S3 client took 886ms
Creating S3 client took 877ms

Исходя из этих приблизительных данных, время создания клиента S3 в сценариях холодного запуска сократилось более чем на треть при использовании версии 2 SDK.

0 голосов
/ 29 апреля 2018

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

После периода бездействия ваш облачный провайдер уронит контейнер, и ваша функция станет неактивной (a.k.a., cold).

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

Вы можете исправить это, оставив ваши функции «теплыми». Один из способов сделать это - добавить cronjob, который время от времени проверяет вашу функцию. Доступен плагин, который делает это под названием serverless-plugin-warmup , и я уверен, что есть еще много подобных.

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