簡體   English   中英

安排 Google Batch 作業在 GCP 上觸發(長時間運行 Python 腳本)

[英]Scheduling a Google Batch job to trigger on GCP (long running Python script)

我所說的“Google Batch”指的是大約一個月前 Google 推出的新服務。

https://cloud.google.com/batch

我有一個 Python 腳本,目前需要幾分鍾才能執行。 然而,對於將在接下來的幾個月內處理的數據,此執行時間將從幾分鍾到幾小時go。 這就是為什么我不使用 Cloud Function 或 Cloud Run 來運行此腳本的原因,這兩者的執行時間最長為 60 分鍾。

Google Batch 是最近出現的,我想探索它作為一種可能的方法來實現我正在尋找的東西,不僅僅是使用 Compute Engine。

但是,整個 inte.net 上的文檔很少,我找不到使用 Cloud Scheduler 來“觸發”已創建的 Batch 作業的方法。 我已經成功地手動創建了一個運行我的 docker 圖像的批處理作業。 現在我需要一些東西來每天觸發這個批處理作業 1x,就是這樣 如果 Cloud Scheduler 可以達到這個目的,那就太好了。

我看過一篇文章,描述了使用 GCP Workflow 在 Cloud Scheduler 確定的 cron 上創建一個新的批處理作業。 問題在於它每次都創建一個新的批處理作業,而不是簡單地重新運行已經存在的批處理作業。 老實說,我什至無法在 GCP 網站上重新運行已經執行的批處理作業,所以我不知道它是否可能。

https://www.intertec.io/resource/python-script-on-gcp-batch

最后,我什至探索了官方的 Google Batch Python 庫,但在其中找不到任何內置的 function 允許我“調用”先前創建的批處理作業並重新運行它。

https://github.com/googleapis/python-batch

有一個誤會。 當您使用 Cloud Run 作業時,您可以創建配置並執行配置。

但是,使用批處理作業,您可以執行配置。 僅此而已,無需提前創建配置。

查看API :創建、獲取、刪除。 不再。

因此,您必須在 Cloud Scheduler 中設置整個 Batch 配置以創建新作業。 注意不要在查詢參數中設置 jobID。

我今天早上為你寫這篇文章作為指南。

它結合使用 Google 的示例和 Cloud Scheduler:

# Used to correctly (!?) form Batch Job
import google.cloud.batch_v1.types

import google.cloud.scheduler_v1
import google.cloud.scheduler_v1.types

import os


project = os.getenv("PROJECT")
number = os.getenv("NUMBER")
location = os.getenv("LOCATION")
job = os.getenv("JOB")

# Batch Job
# Create Batch Job using batch_v1.types
# Alternatively, create this from scratch
batch_job = google.cloud.batch_v1.types.Job(
    priority=0,
    task_groups=[
        google.cloud.batch_v1.types.TaskGroup(
            task_spec=google.cloud.batch_v1.types.TaskSpec(
                runnables=[
                    google.cloud.batch_v1.types.Runnable(
                        container=google.cloud.batch_v1.types.Runnable.Container(
                            image_uri="gcr.io/google-containers/busybox",
                            entrypoint="/bin/sh",
                            commands=[
                                "-c",
                                "echo \"Hello world! This is task ${BATCH_TASK_INDEX}. This job has a total of ${BATCH_TASK_COUNT} tasks.\""
                            ],
                        ),
                    ),
                ],
                compute_resource=google.cloud.batch_v1.types.ComputeResource(
                    cpu_milli=2000,
                    memory_mib=16,
                )
            ),
            task_count=1,
            parallelism=1,
        ),
    ],
    allocation_policy=google.cloud.batch_v1.types.AllocationPolicy(
        location=google.cloud.batch_v1.types.AllocationPolicy.LocationPolicy(
           allowed_locations=[
            f"regions/{location}",
           ], 
        ),
        instances=[
            google.cloud.batch_v1.types.AllocationPolicy.InstancePolicyOrTemplate(
                policy=google.cloud.batch_v1.types.AllocationPolicy.InstancePolicy(
                    machine_type="e2-standard-2",
                ),
            ),
        ],
    ),
    labels={
        "stackoverflow":"73966292",
    },
    logs_policy=google.cloud.batch_v1.types.LogsPolicy(
        destination=google.cloud.batch_v1.types.LogsPolicy.Destination.CLOUD_LOGGING,
    ),
)

# Convert the Google Batch Job into JSON
# Google uses Proto Python
# https://proto-plus-python.readthedocs.io/en/stable/messages.html?highlight=JSON#serialization
batch_json=google.cloud.batch_v1.types.Job.to_json(batch_job)
print(batch_json)

# Convert JSON to bytes as required for body by Cloud Scheduler
body=batch_json.encode("utf-8")

# Run hourly on the hour (HH:00)
schedule = "0 * * * *"

parent = f"projects/{project}/locations/{location}"
name = f"{parent}/jobs/{job}"
uri = f"https://batch.googleapis.com/v1/{parent}/jobs?job_id={job}"

service_account_email = f"{number}-compute@developer.gserviceaccount.com"

scheduler_job = google.cloud.scheduler_v1.types.Job(
    name=name,
    description="description",
    http_target=google.cloud.scheduler_v1.types.HttpTarget(
        uri=uri,
        http_method=google.cloud.scheduler_v1.types.HttpMethod(
            google.cloud.scheduler_v1.types.HttpMethod.POST,
        ),
        oauth_token=google.cloud.scheduler_v1.types.OAuthToken(
            service_account_email=service_account_email,
        ),
        body=body,
    ),
    schedule=schedule,
)

scheduler_json=google.cloud.scheduler_v1.Job.to_json(scheduler_job)
print(scheduler_job)

request = google.cloud.scheduler_v1.CreateJobRequest(
    parent=parent,
    job=scheduler_job,
)

scheduler_client = google.cloud.scheduler_v1.CloudSchedulerClient()
print(
    scheduler_client.create_job(
        request=request
    )
)

您可以測試使用:

BILLING="..."
PROJECT="..."
LOCATION="..." # E.g. us-west1

JOB="tester"

ACCOUNT="tester"
EMAIL="${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com"

# Create Project and enable Billing
gcloud projects create ${PROJECT}
gcloud beta billing projects link ${PROJECT} \
--billing-account=${BILLING}

# Enable Cloud Scheduler and Cloud Run
SERVICES=(
  "batch"
  "cloudscheduler"
  "compute"
)
for SERVICE in ${SERVICES[@]}
do
  gcloud services enable ${SERVICE}.googleapis.com \
  --project=${PROJECT}
done

# Create Service Account
gcloud iam service-accounts create ${ACCOUNT} \
--project=${PROJECT}

gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \
--iam-account=${EMAIL} \
--project=${PROJECT}

# IAM
# https://cloud.google.com/iam/docs/understanding-roles#cloud-scheduler-roles
ROLES=(
  "roles/batch.jobsEditor"
  "roles/cloudscheduler.admin"
)
for ROLE in ${ROLES[@]}
do
  gcloud projects add-iam-policy-binding ${PROJECT} \
  --member=serviceAccount:${EMAIL} \
  --role=${ROLE}
done

# ActAs
NUMBER=$(\
  gcloud projects describe ${PROJECT} \
  --format="value(projectNumber)")
COMPUTE_ENGINE="${NUMBER}-compute@developer.gserviceaccount.com"
gcloud iam service-accounts add-iam-policy-binding ${COMPUTE_ENGINE} \
--member=serviceAccount:${EMAIL} \
--role="roles/iam.serviceAccountUser" \
--project=${PROJECT}

然后:

python3 -m venv venv
source venv/bin/activate

# Or requirements.txt
python3 -m pip install google-cloud-batch
python3 -m pip install google-cloud-scheduler

export JOB
export LOCATION
export NUMBER
export PROJECT

export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/${ACCOUNT}.json

python3 main.py

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM