TLDR

Вы можете запускать длительные задания на полностью настраиваемой виртуальной машине с помощью нового пакетного сервиса Google Cloud Platform (GCP). Ссылку на Github с нашим рабочим образцом вы можете найти здесь.

Для кого этот блог?

Если вы ищете бессерверный способ запуска длительных заданий, не ищите дальше. GCP недавно запустила пакетную службу, управляемую услугу, которая позволяет вам делать именно это. Пакетная обработка позволяет обучать алгоритмы машинного обучения, конвертировать видеофайлы или обрабатывать большие объемы данных. Хотя это полностью управляемая услуга, вы платите только за используемую виртуальную машину. Поскольку виртуальная машина автоматически выключается после завершения, такое бессерверное развертывание может сэкономить вам много средств по сравнению с машиной, которая работает постоянно.

Предпосылки

Чтобы следить за блогом, вам понадобится следующее:

  • Базовые знания Докера
  • Базовые знания Python
  • Проект с платежным адресом в GCP
  • Установка Docker и gcloud CLI

Пакетно

Одному из наших клиентов необходимо было ежедневно конвертировать большие видеофайлы .mfx (до 30 гигабайт) в более удобный сжатый формат .mp4. Такая конвертация, в зависимости от множества факторов, может длиться от 30 минут до нескольких часов. Одной из возможностей является использование Cloud Run, однако это решение не будет работать для заданий, превышающих 60 минут.

По-прежнему занимаясь поиском бессерверного решения, мы предложили использовать новый пакетный сервис GCP. С помощью пакетной службы вы можете запустить задание на виртуальной машине с помощью простого HTTP-запроса. Об остальном, а именно о подготовке, запуске и завершении работы виртуальной машины, заботятся автоматически. Таким образом, требуется только минимальная настройка, и вы также платите только за то, что используете. Поскольку вы используете виртуальные машины, вы можете установить любую зависимость или программное обеспечение, необходимое для выполнения вашей рабочей нагрузки.

Давайте попробуем этот новый сервис, запустив «длинный» скрипт Python. Мы создадим собственный файл dockerfile и скрипт Python, создадим его и отправим в реестр контейнеров Google (GCR). Здесь пакетный процесс найдет образ контейнера и запустит контейнер на автоматически подготовленной виртуальной машине. Машина будет выключена автоматически.

Не нужно дальнейших объяснений? Пример рабочего кода можно найти здесь.

Первый шаг — создать папку, в которую вы поместите на корневом уровне: (1) файл Dockerfile и (2) скрипт Python с именем main.py.

import sys
import time

def long_running_function(n):
    for i in range(n):
        time.sleep(1)
        print(f"Processed {i+1} out of {n} items...")

if __name__ == "__main__":
    try:
        long_running_function(60)
    except Exception as err:
        print("Error occurred:", err)
        sys.exit(1)

Эта функция принимает единственный аргумент n, который определяет количество обрабатываемых элементов. Затем он запускает цикл, который засыпает на одну секунду и выводит сообщение о ходе выполнения для каждого обработанного элемента.

Dockerfile довольно прост. Здесь вы можете использовать базовый образ (например, python:3), поместить файл main.py в рабочий каталог и указать правильную точку входа, чтобы Docker знал, что выполнять при запуске контейнера. В этот файл вы можете добавить другие зависимости, такие как GCSfuse или Cloud SQL.

Ниже показано, как может выглядеть ваш Dockerfile.

FROM python:3

WORKDIR /usr/src/app

#COPY requirements.txt ./
#RUN pip install --no-cache-dir -r requirements.txt

COPY main.py ./main.py

ENTRYPOINT ["python", "/usr/src/app/main.py"]

Теперь, чтобы создать и отправить этот образ, выполните следующее:

docker build -t eu.gcr.io/<your project name>/blog_test .

docker push eu.gcr.io/<your project name>/blog_test

Первая команда Docker создает новый образ Docker из файла Dockerfile в текущем каталоге и помечает его тегом с именем eu.gcr.io/‹имя вашего проекта›/blog_test. Адаптируйте URL-адрес в соответствии с вашим предпочтительным местоположением (например, us.gcr.io вместо eu.gcr.io). Вторая команда помещает изображение в регистр.

Вот и все!

Теперь вы можете запустить пакетное задание. Здесь у вас есть несколько вариантов, либо напрямую с gcloud, через клиентскую библиотеку (доступную на Python, Java или других языках), либо через HTTP-запрос. В приведенном ниже примере мы используем gcloud. Для этого создайте config.json со следующим содержимым (не забудьте заменить имя вашего проекта):

{
    "taskGroups": [
        {
            "taskSpec": {
                "runnables": [
                    {
                        "container": {
                          "imageUri": "eu.gcr.io/<your project name here>/blog_test"
                        }
                    }
                ],
                "computeResource": {
                    "cpuMilli": 1000,
                    "memoryMib": 2000
                }
            }
        }
    ],
  "logsPolicy": {
    "destination": "CLOUD_LOGGING"
  }
}
  • imageUri: имя и расположение изображения (определяется тегом docker).
  • cpuMilli: миллисекунды на процессор-секунду. Это означает, что задача будет использовать 2 процессора.
  • memoryMib: память (в мегабайтах).
  • назначение: чтобы иметь возможность просматривать журналы в журнале Cloud.

Откройте терминал, перейдите в свой рабочий каталог и запустите:

gcloud batch jobs submit testjob  --location europe-north1 --config config.json

После выполнения команды задание будет отправлено в Google Cloud Batch в указанном регионе, и служба начнет выделять необходимые ресурсы и запускать задание в соответствии с конфигурацией, указанной в config.json.

Посетите: https://console.cloud.google.com/batch/jobs?project=‹название вашего проекта здесь›

Использованная литература:

https://cloud.google.com/batch/docs/get-started