Как я могу поддерживать функции Google Cloud Functions?

Я знаю, что это упускает смысл использования облачных функций в первую очередь, но в моем конкретном случае я использую облачные функции, потому что это единственный способ связать Next.js с хостингом Firebase. Мне не нужно делать это рентабельным и т. д.

С учетом сказанного, время холодной загрузки для облачных функций просто невыносимо и не готово к производству, в среднем от 10 до 15 СЕКУНД для моего шаблона.

Я наверняка смотрел это видео от Google (https://thewikihow.com/video_IOXrwFqR6kY), в котором рассказывается о том, как уменьшить время холодной загрузки. Вкратце: 1) Обрезать зависимости, 2) Метод проб и ошибок для версий зависимостей для кеша в сети Google, 3) Ленивая загрузка.

Но эй, 1) я могу обрезать не так много зависимостей. 2) Как мне узнать, какая версия больше кэшируется? 3) Зависимостей так много, что я могу загружать их лениво.

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

Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
28
0
7 936
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Вы не первый, кто спрашивает ;-)

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

Из вашего вопроса неясно, но я предполагаю, что ваша функция предоставляет конечную точку HTTP. В этом случае найдите службу проверки работоспособности или cron, которую можно настроить для выполнения HTTP-вызова каждые x секунд | минут, и укажите ее на свой объект Function.

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

Спасибо за ответы! Я думаю, что Дуг (другой ответчик) прав, и я цитирую: «Даже если вы можете сохранить работоспособность одного экземпляра, выполнив pinging его, система может развернуть любое количество других экземпляров для обработки текущей нагрузки. Эти новые экземпляры будут иметь холодный запуск ». Так что пинг не стал бы хорошим решением. И я попробовал, холодный старт по-прежнему случаен ...

harrisonlo 12.08.2018 04:12

При низких объемах (ping) маловероятно, что служба попытается масштабироваться с помощью дополнительных экземпляров. В вашем вопросе указано, что вас не интересуют альтернативные решения и есть ли способ сохранить экземпляр в живых. На данный момент это единственное решение этой проблемы.

DazWilkin 12.08.2018 17:18
Ответ принят как подходящий

Со всеми "бессерверными" поставщиками вычислений всегда будет какая-то форма затрат на холодный запуск, которую вы не сможете устранить. Даже если вы можете сохранить работоспособность одного экземпляра с помощью команды ping, система может развернуть любое количество других экземпляров для обработки текущей нагрузки. Эти новые экземпляры будут иметь холодный запуск. Затем при уменьшении нагрузки ненужные экземпляры будут отключены.

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

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

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

Oliver Dixon 02.10.2019 20:41

Вы можете запустить его через задание cron, как описано здесь: https://cloud.google.com/scheduler/docs/creating

Использование Google Scheduler - мудрое решение, но его реализация не так проста. Пожалуйста, проверьте моя статья для подробностей. Примеры функций:

myHttpFunction: functions.https.onRequest((request, response) => {
  // Check if available warmup parameter.                                   
  // Use  request.query.warmup parameter if warmup request is GET.                                   
  // Use request.body.warmup parameter if warmup request is POST.                                   
  if (request.query.warmup || request.body.warmup) {
    return response.status(200).type('application/json').send({status: "success", message: "OK"});
  }
});
myOnCallFunction: functions.https.onCall((data, context) => {
  // Check if available warmup parameter.
  if (data.warmup) {
    return {"success": true};
  }
});

Примеры команд gcloud cli:

gcloud --project = "my-awesome-project" scheduler jobs create http  warmupMyOnCallFuntion --time-zone "America/Los_Angeles" --schedule = "*/5 5-23 * * *" --uri = "https://us-central1-my-awesome-project.cloudfunctions.net/myOnCallFuntion" --description = "my warmup job" --headers = "Content-Type=application/json" --http-method = "POST" --message-body = "{\"data\":{\"warmup\":\"true\"}}"

gcloud --project = "my-awesome-project" scheduler jobs create http  warmupMyHttpFuntion --time-zone "America/Los_Angeles" --schedule = "*/5 5-23 * * *" --uri = "https://us-central1-my-awesome-project.cloudfunctions.net/myHttpFuntion?warmup=true" --description = "my warmup job" --headers = "Content-Type=application/json" --http-method = "GET"

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

Как сделать лямбду быстрее?

  1. Сохраняйте размер вашего пакета как можно меньшим (удалите все большие библиотеки, в которых используется небольшая часть) - держите размер пакета не более 20 МБ. При каждом холодном запуске этот пакет загружается и распаковывается.
  2. Попробуйте инициализировать при запуске приложения только те части, которые вам нужны. Nodejs - https://gist.github.com/Rich-Harris/41e8ccc755ea232a5e7b88dee118bcf5
  3. Если вы используете технологию JVM для своих сервисов, попробуйте перенести их на Graalvm, где накладные расходы при загрузке сведены к минимуму.
    • micronaut + graalvm
    • quarkus + graalvm
    • helidon + graalvm
  4. Используйте конфигурации облачной инфраструктуры, чтобы уменьшить количество холодных запусков.

В 2020 году холодный старт не будет такой болезненной, как несколько лет назад. Я бы больше сказал об AWS, но уверен, что все вышеперечисленное хорошо работает для любого облачного провайдера.

В конце 2019 года AWS ввела поддержку параллелизма Lambda - https://aws.amazon.com/about-aws/whats-new/2019/12/aws-lambda-announces-provisioned-concurrency/, вам не о чем беспокоиться так много о потеплении.

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

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

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

Типичная облачная функция холодный:

Типичная облачная функция теплый:

Есть несколько способов справиться с проблемой холодного запуска:

  • Уменьшите зависимости и количество кода. Как я уже говорил, облачные функции лучше всего подходят для выполнения отдельных задач. Это уменьшит общий размер пакета, который должен быть загружен на сервер между получением запроса и выполнением кода, что значительно ускорит процесс.
  • Еще один более хитрый способ - настроить облачный планировщик на периодическую отправку запросов на разминку в вашу облачную функцию. GCP имеет обширный уровень бесплатного пользования, который позволяет использовать 3 планировщика и 2 миллиона вызовов облачных функций (в зависимости от использования ресурсов). Таким образом, в зависимости от количества облачных функций вы можете легко запланировать http-запрос каждые несколько секунд. Для ясности я разместил под этим постом фрагмент, который развертывает облачную функцию и планировщик, который отправляет запросы на разминку.

Если вы думаете, что устранили проблему холодного запуска, вы также можете принять меры для ускорения фактического времени выполнения:

  • Я переключился с Python на Golang, что дало мне двузначное увеличение производительности с точки зрения фактического времени выполнения. Скорость Golang сравнима с Java или C++.
  • Объявите переменные, особенно клиенты GCP, такие как хранилище, pub / sub и т. д., На глобальном уровне (источник). Таким образом, будущие вызовы вашей облачной функции будут повторно использовать эти объекты.
  • Если вы выполняете несколько независимых действий в облачной функции, вы можете сделать их асинхронными.
  • И снова чистый код и меньшее количество зависимостей также улучшают время выполнения.

Фрагмент:

# Deploy function
gcloud functions deploy warm-function \
  --runtime=go113 \
  --entry-point=Function \
  --trigger-http \
  --project=${PROJECT_ID} \
  --region=europe-west1 \
  --timeout=5s \
  --memory=128MB

# Set IAM bindings
gcloud functions add-iam-policy-binding warm-function \
  --region=europe-west1 \
  --member=serviceAccount:${PROJECT_ID}@appspot.gserviceaccount.com \
  --role=roles/cloudfunctions.invoker

# Create scheduler
gcloud scheduler jobs create http warmup-job \
  --schedule='*/5 * * * *' \
  --uri='https://europe-west1-${PROJECT_ID}.cloudfunctions.net/warm-function' \
  --project=${PROJECT_ID} \
  --http-method=OPTIONS \
  --oidc-service-account-email=${PROJECT_ID}@appspot.gserviceaccount.com \
  --oidc-token-audience=https://europe-west1-${PROJECT_ID}.cloudfunctions.net/warm-function

Другие вопросы по теме