Как сохранить необходимое количество контейнеров с функцией AWS Lambda в тепле - PullRequest
0 голосов
/ 06 июля 2018

В моем проекте есть REST API, который реализован на AWS API Gateway и AWS Lambda. Поскольку функции AWS Lambda не содержат сервера и не сохраняют состояние, а мы делаем вызов, AWS запускает контейнер с кодом функции Lambda, которая обрабатывает наш вызов. Согласно документации AWS после завершения выполнения лямбда-функции AWS не останавливает контейнер, и мы можем обработать следующий вызов в этом контейнере. Такой подход повышает производительность сервиса - только во время первого вызова AWS тратит время на запуск контейнера (холодный запуск функции Lambda), а все последующие вызовы выполняются быстрее, поскольку они используют один и тот же контейнер (теплый запуск).

В качестве следующего шага для повышения производительности мы создали задачу cron, которая периодически вызывает нашу функцию Lambda (для этого мы используем правила Cloudwatch). Такой подход позволяет сохранить функцию Lambda «теплой», что позволяет избежать остановки и перезапуска контейнеров. То есть когда реальный пользователь вызовет наш REST API, Lambda не будет тратить время на запуск нового контейнера.

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

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

Ответы [ 4 ]

0 голосов
/ 20 января 2019

Если вы используете серверный фреймворк с AWS Lambda, вы можете использовать этот плагин , чтобы поддерживать все ваши лямбды в тепле с определенным уровнем параллелизма.

0 голосов
/ 25 июля 2018

Мы используем Java-лямбды (весенние сапоги) и пришли к тому же решению, что и ответ Куш Вьяса выше, который работает очень хорошо.

Однако во время нагрузочного тестирования мы обнаружили, что в течение периода, когда выполнялась «функция контроллера», часто возникал законный пользовательский запрос, что снова вызывало неизбежный холодный запуск ...

Итак, теперь в нашей «функции контроллера» у нас есть обычное число одновременных запросов разогрева по X, однако при каждом пятом выполнении функции мы вызываем нашу целевую лямбду еще 2 раза. Теория заключается в том, что в конечном итоге X + 2 лямбда будут оставаться теплыми, но для 4 из 5 разогревающих вызовов все равно будет 2 избыточных лямбды, которые могут обслуживать запросы пользователей.

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

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

Я хотел бы поделиться небольшим, но полезным советом, который мы используем, чтобы уменьшить «наблюдаемую пользователем» задержку, связанную с холодными запусками. В нашем случае функция Lambda обрабатывает HTTP-запросы от внешнего интерфейса через AWS API Gateway, в частности, выполняет функцию поиска, когда пользователь вводит что-то в поле ввода. Обычно пользователь начинает печатать с некоторой задержкой после рендеринга пользовательского интерфейса, поэтому у нас есть некоторое время, чтобы выполнить ping-вызов нашей функции Lambda для ее прогрева. И когда пользователь будет отправлять запросы на сервер, скорее всего Lambda будет готова к работе.

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

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

0 голосов
/ 11 июля 2018

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

В качестве альтернативы Вы можете перейти к основанию" Обходной путь ", если вы не заинтересованы в чтении.

Для людей, которые не знают о холодных запусках, прочитайте этот блог пост, чтобы лучше понять его. Чтобы описать это вкратце:

Холодный старт

  • Когда функция выполняется в первый раз или после обновлен код функций или конфигурация ресурса, контейнер будет развернулся, чтобы выполнить эту функцию. Весь код и библиотеки будут загружен в контейнер для его выполнения. Код будет затем запустите, начиная с кода инициализации. Инициализация Код - это код, написанный вне обработчика. Этот код запускается только когда контейнер создается в первый раз. Наконец, лямбда обработчик выполнен. Этот процесс настройки является то, что считается холодным начать.
  • Для повышения производительности Lambda имеет возможность повторно использовать созданные контейнеры. по предыдущим вызовам. Это позволит избежать инициализации нового контейнер и загрузка кода. Только код обработчика будет казнены. Тем не менее, вы не можете зависеть от контейнера из предыдущего вызов для повторного использования. если вы не изменили код и не слишком прошло много времени, Lambda может повторно использовать предыдущий контейнер.
  • Если вы измените код, конфигурацию ресурса или какое-то время прошло с момента предыдущего вызова, новый контейнер будет инициализируется, и вы будете испытывать холодный старт.

Теперь рассмотрим следующие сценарии для лучшего понимания:

  • Рассмотрим функцию Lambda, которая в этом примере вызывается впервые. Lambda создаст контейнер, загрузит код в контейнер и запустит код инициализации. Затем будет выполнен обработчик функции. Этот вызов будет иметь холодный старт . Как упоминалось в комментариях, функция занимает 15 секунд. Через минуту функция вызывается снова. Lambda, скорее всего, будет повторно использовать контейнер из предыдущего вызова. Этот вызов не будет испытывать холодный запуск.
  • Теперь рассмотрим второй сценарий , где второй вызов выполняется через 5 секунд после первого вызова. Поскольку предыдущей функции требуется 15 секунд для завершения, и она еще не завершена, новый вызов должен будет создать новый контейнер для выполнения этой функции. Поэтому этот вызов будет испытывать холодный старт.

Теперь перейдем к первой части проблемы, которую вы решили:

Что касается предотвращения холодных запусков, это возможно, однако, это не гарантируется, общий обходной путь будет поддерживать только один контейнер функции Lambda. Для этого вы должны запустить событие CloudWatch, используя событие расписания (выражение cron), которое будет вызывать вашу лямбда-функцию каждые пару минут, чтобы поддерживать ее в рабочем состоянии.


Обходной путь:

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

Как уже говорилось, ниже приводится описание того, как вы можете хранить несколько контейнеров для своей функции в тепле одновременно:

  • У вас должно быть Правило событий CloudWatch, которое запускается по расписанию . Это расписание может быть фиксированной скоростью или выражением cron. Например, вы можете настроить это правило на срабатывание каждые 5 минут. Вы затем укажите лямбда-функцию (функцию контроллера) в качестве цели этого правила.

  • Ваша функция Lambda контроллера затем вызовет функцию Lambda (функцию, которую вы хотите сохранить в тепле) для стольких одновременно работающих контейнеров, сколько пожелаете.

Здесь нужно учесть несколько вещей:

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

  2. Вам также необходимо убедиться, что вы не ограничиваетесь вызовом Invoke Lambda API, если вы вызываете его повторно. Ваш лямбда функция должна быть написана для обработки этого регулирования, если оно происходит и рассмотрите возможность добавления задержки между вызовами API, чтобы избежать регулирования.

В конце это решение может уменьшить холодные запуски, но это увеличит затраты и не гарантирует, что холодные запуски произойдут, поскольку они неизбежны при работе с Lambda. Если вашему приложению требуется более быстрое время отклика, чем то, что происходит с Лямбда холодный старт, я бы порекомендовал изучить ваш сервер на экземпляре EC2.

...