Холодный запуск Lambda — копирование файла из S3

#aws-lambda

#aws-lambda

Вопрос:

У меня есть Java-лямбда, которая в данный момент копирует файл из S3 в / tmp. Это занимает 6-10 секунд в зависимости от размера экземпляра Lambda. Файл повторно используется при новых вызовах, которые используют тот же экземпляр Lambda. Однако трафик очень интенсивный, и я мог видеть, что поступает более 50 одновременных запросов, и копирование с холодного запуска из S3 неприемлемо…

Есть ли лучший способ «предварительной загрузки» данных в экземпляр Lambda, чем копирование из S3? Как насчет HTTP-запроса для извлечения кэшированной копии из Cloudfront. Любые другие «хитрости» для ускорения холодного запуска при наличии требований к данным начального запуска?

Ответ: ДА, Смотрите ниже

Комментарии:

1. Насколько велик этот файл?

2. Конкретный файл, о котором идет речь, составляет 1,5 МБ, который я извлек из S3 с помощью GetObject. Я решил развернуть свои файлы на своем хостинге, доступном CloudFront, с использованием Gzip и попробовать этот HTTP-запрос, чтобы перенести данные в Lambda. Отличные новости, у меня все заработало, и я увидел, что время инициализации моего Lambda сократилось с 12-15 секунд примерно до 4 секунд (при использовании экземпляра размером 640 МБ), а файловый поток https записывается в / tmp блоками по 16 КБ. Размер блока, похоже, не имеет большого значения в моем тестировании, но я хотел ограничить выделение памяти в Lambda. Я отредактирую свой вопрос и опубликую код.

Ответ №1:

Ответ: ДА

Быстрее извлекать из корзины хостинга S3, поддерживаемой CloudFront и использующей GZip. Для файла размером 1,5 МБ я заметил улучшение производительности с 12 секунд до всего лишь 4 секунд. Вот код, который я написал для этой цели:

 void getFile(String remoteUrl) throws Exception {

    URL url = new URL(remoteUrl); 
    HttpsURLConnection con = (HttpsURLConnection)url.openConnection();

    con.setRequestProperty("Accept-Encoding", "gzip");

    BufferedInputStream bis;
    if ("gzip".equals(con.getContentEncoding())) {
        bis = new BufferedInputStream(new GZIPInputStream(con.getInputStream()));
    }
    else {
        bis = new BufferedInputStream(con.getInputStream());
    }

    String getPath = url.getPath();
    String fileName = "/tmp/" getPath.substring(getPath.lastIndexOf('/')   1);

    BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileName));
    byte[] buff = new byte[16 * 1024];
    int len;
    while ((len = bis.read(buff)) > 0)
        out.write(buff, 0, len);
    bis.close();
    out.close();
}
  

Я надеюсь, что это поможет кому-то еще.

Обрыв

Комментарии:

1. Приведенный выше код предполагает URL-адрес HTTPS. Дальнейшие улучшения производительности могут быть сделаны с использованием HTTP (используйте на свой страх и риск!)