[번역] GCP 배치에서 Python 스크립트를 실행하는 방법

데이터셰프
2022-12-28
조회수 1251



최근 Google 은 Batch 라는 Google Cloud 제품 의 일부로 완전히 새로운 서비스를 발표했습니다 .

GCP 배치 란 무엇 ?

Google 문서 에서 : “ …Batch를 사용하면 각각 작업을 실행하는 데 필요한 리소스를 자동으로 프로비저닝하고 활용하는 작업을 만들고 실행할 수 있습니다. ” 이 서비스는 최대 224개의 CPU와 896GB의 메모리를 제공하므로 무거운 작업에 적합합니다.


Batch를 사용해야할 이유

Google Cloud 는 서버 관리 대신 모든 작업을 수행하는 다양한 서비스를 제공합니다. 이러한 유형의 서비스는 Cloud Functions 를 포함하여 "서버없는" 레이블이 붙은 상태로 제공됩니다 .

Cloud Functions 는 이벤트 기반 아키텍처를 위한 완벽한 후보입니다. 이 예를 들어 보겠습니다. "처리되지 않은" 스토리지 버킷에 파일을 업로드하면 구성한 Pub/Sub 주제로 알림이 전송되고 Cloud 함수가 트리거됩니다. 그런 다음 Cloud Function은 업로드된 파일을 처리하고 "처리된" 저장소 버킷에 업로드합니다. 2세대 Cloud Function 이 제공 하는 1시간 제한 시간, 32GB 메모리 및 8개 CPU와 결합된 이 수준의 단순성 은 이와 같은 시나리오를 처리할 때 가장 적합한 선택입니다.

몇 달이 지나고 파일이 제대로 업로드되고 처리되다가 갑자기 Cloud Function 이 실패했다는 알림을 받습니다. 갑자기 새 서비스를 사용하는 "달콤한" 단계가 사라졌습니다. 무엇이 잘못되었는지 문제 해결을 시작하고 업로드된 파일의 크기가 수백만 항목이 포함된 몇 GB인지 확인합니다. Cloud 함수 가 수행하는 복잡한 처리와 함께 파일 크기로 인해 Cloud 함수 가 1시간 제한 시간에 도달하게 됩니다.

다행스럽게도 새로운 Batch 서비스에는 timeout 이 없습니다. 즉, 결과를 반환할 때까지 스크립트를 실행합니다. Batch 는 bash 스크립트 또는 Docker 이미지 의 두 가지 배포 유형을 허용합니다 . Python Cloud Function 을 Batch 내부 로 마이그레이션해야 하므로 Python 코드 를 포함할 Docker 이미지 가 필요합니다 .


Docker 이미지 만들기

코드와 Dockerfile 을 포함할 "batch" 폴더를 만드는 것으로 시작하겠습니다. 폴더로 이동하여 다음을 실행하는 Python 가상 환경을 만듭니다.



그런 다음 가상 환경을 활성화합니다.


이제 코드 작업을 시작할 준비가 되었습니다.  Python 스크립트 의 가장 간단한 예를 만들 것입니다 — " Hello from Batch "를 인쇄합니다. 따라서 main.py 는 다음과 같습니다.


main.py 스크립트 를 실행하기 위해 필요한 요구 사항을 Docker 이미지 에 알려야 하므로 다음을 실행 하여 요구 사항 파일을 생성해 보겠습니다.


마지막으로 Dockerfile 을 작성합니다.


이것은 python3.8 이미지 를 가져 오고 스크립트에 필요한 요구 사항을 설치하고 마지막으로 스크립트를 실행 하는 정말 간단한 Dockerfile 입니다. 아래가 우리의 작은 프로젝트의 구조입니다.



이제 Docker 이미지를 빌드할 준비가 되었습니다. 우리의 목표는 빌드된 Docker 이미지를 GCP Artifact Registry 에 업로드하여 Batch 작업 에 쉽게 사용할 수 있도록 하는 것입니다 . 아직 만들지 않은 경우 Docker 이미지를 저장하기 위한 리포지토리를 만듭니다. 이름을 "batch-tutorial"로 지정합니다.

이미지를 Artifact Registry 에 게시하려면 이미지에 GCP 가 지정한 특정 형식으로 태그를 지정해야 합니다 .

  • • LOCATION은 리포지토리의 지역 또는 다중 지역 위치입니다.
  • • PROJECT는 Google Cloud 프로젝트 ID입니다.
  • • REPOSITORY는 이미지가 저장된 저장소의 이름입니다.
  • • IMAGE는 리포지토리에 있는 이미지의 이름입니다.
  • • TAG는 삭제하려는 버전의 태그입니다.

따라서 다음을 실행하여 Docker 이미지를 빌드합니다.


Docker 이미지 배포

특정 태그로 Docker 이미지를 성공적으로 빌드 했으므로 이제 Docker 이미지를 Artifact Registry에 게시할 준비가 되었습니다 . 다음을 실행하여 수행되는 이미지 배포를 시도하기 전에 GCP 및 Docker 레지스트리 로 인증 되었는지 확인하세요 .


'Docker 이미지를 배포한다'는 것은 하면 Batch 작업을 생성할 준비가 모두 완료 되었다는 것입니다. 계속 진행하겠습니다.


배치 작업 만들기

퍼즐의 마지막 조각은 Batch 작업을 만드는 것입니다. https://console.cloud.google.com/batch 로 이동 하여 화면 상단에 있는 만들기를 클릭합니다 . Batch 작업 을 생성하기 위한 새 화면이 열립니다. Batch 로 선택할 수 있는 regions의 수가 제한되어 있으며 서비스가 아직 미리보기 모드에 있을 것입니다. 컨테이너 이미지 URL의 경우 이전 단계에서 푸시한 Docker 이미지의 URL을 붙여넣고 맨 아래에서 일괄 작업에 할당할 리소스 수를 선택하고 만들기를 클릭합니다. 이제 GCP는 사용자가 요청한 필요한 리소스를 할당해야 하므로 처음에는 작업이 대기 상태가 됩니다. 리소스가 할당되면 상태가 "예약됨"으로 변경됩니다. 마지막으로 Batch 작업이 Python 스크립트 실행을 시작하고 상태가 실행 중으로 변경됩니다.

Batch 작업이 성공(또는 실패) 하면 자세히 보기에서 열고 Cloud Logging 을 클릭할 수 있습니다 . 우리의 경우 배치 작업이 " Hello from Batch "를 인쇄한 것을 볼 수 있습니다.

이 모든 것이 간단한 " Hello World " 예제에 적합해 보이지만 우리는 Batch 작업이 이벤트 기반 Cloud Functions 의 대안 이라고 이야기 했습니다. Cloud Functions만큼 간단하게 이벤트 기반 Batch 작업을 생성할 수 없습니다. 대신 GCP Workflows 를 사용해야 합니다.


GCP Workflows 사용한 이벤트 기반 Batch 작업

다시 시나리오를 상상해 봅시다. "처리되지 않은" 스토리지 버킷에 파일을 업로드하면 파일이 처리되고 저장됩니다. 이전 시나리오와의 차이점은 이제 파일이 Batch 작업으로 처리된다는 것입니다.

GCP 저장소 에서 파일을 다운로드 하려면 먼저 필요한 패키지를 설치해야 합니다.


pip install google - 클라우드 - 스토리지



이제 Python 코드를 작성해 보겠습니다.

from google.cloud import storage
from loguru import logger as log
import os

from google.cloud import storage

from loguru import logger as log

import os

 

def download_file(bucket_name, source_blob_name, destination_file_name):

    # The ID of GCS bucket

    bucket_name = os.environ.get(“BUCKET”)

    # The ID of GCS object

    source_blob_name = os.environ.get(“FILE”)

    # The path to which the file should be downloaded

    destination_file_name = “batch-tutorial.txt”

    storage_client = storage.Client()

    bucket = storage_client.bucket(bucket_name)

    blob = bucket.blob(source_blob_name)

    blob.download_to_filename(destination_file_name)

    log.info(f”Downloaded storage object ‘{source_blob_name}’ from bucket ‘{bucket_name}’ to local file ‘{destination_file_name}’”)

 

    if __name__ == “__main__”:

        download_file(bucket_name=””, source_blob_name=””, destination_file_name=””)



버킷 이름과 소스 파일이라는 두 가지 환경 변수를 사용하고 있음을 알 수 있습니다. 이들은 여전히 어디에도 정의되어 있지 않지만 Workflow 내부의 다음 단계에서 정의할 것입니다 .

이제 다음을 실행해 보겠습니다.


Dockerfile 의 내용은 이전 " Hello from Batch " 예제 와 정확히 동일합니다 .

이제 Docker 이미지 를 빌드하고 푸시해 보겠습니다 . 이전과 동일한 명령을 사용하고 있으며 이미지 태그만 변경하고 있습니다.


Docker 이미지가 Artifact Registry 로 푸시되었으므로 Workflow 작업을 시작할 준비가 되었습니다 . 워크플로는 '처리되지 않은' 버킷에 업로드할 때마다 트리거되고 버킷에서 업로드된 파일을 알려주는 이벤트를 수신합니다.

먼저 GCP Workflows 로 이동하여 만들기 를 클릭합니다 . 그러면 워크플로 의 이름을 설정 하고 리전과 서비스 계정을 선택하고 선택적으로 트리거를 구성 해야 하는 새 화면이 열립니다 . 선택한 서비스 계정에 Batch API 를 호출할 수 있는 충분한 권한이 있는지 확인하세요 .

버킷에 대한 모든 "파일 업로드" 에서 워크플로 를 실행하려고 하므로 Add new trigger를 클릭하고 Eventarc 를 선택합니다 . 여기에서 이벤트 공급자 로 Cloud Storage 를 결정 하고 "처리되지 않은" 버킷을 찾아 선택 하고 트리거 이벤트로 google.cloud.storage.object.v1.finalized 를 선택합니다.

이제 다음과 같은 워크플로 를 정의할 준비가 되었습니다.

main:

  params: [event]

  steps:

  - init:

      assign:

        - projectId: ${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}

        - region: "europe-north1"

        - batchApi: "batch.googleapis.com/v1"

        - batchApiUrl: ${"https://" + batchApi + "/projects/" + projectId + "/locations/" + region + "/jobs"}

        - imageUri: "europe-west3-docker.pkg.dev/PROJECT/batch-tutorial/batch:event-driven-tutorial"

        - jobId: ${"job-" + string(int(sys.now()))}

  - log_event:

      call: sys.log

      args:

          text: ${event}

          severity: INFO

  - extract_bucket_and_file:

      assign:

      - bucket: ${event.data.bucket}

      - file: ${event.data.name}

  - logCreateBatchJob

      call: sys.log

      args:

        data: ${"Creating and running the batch job " + jobId}

  - createAndRunBatchJob:

      call: http.post

      args:

        url: ${batchApiUrl}

        query:

          job_id: ${jobId}

        headers:

          Content-Type: application/json

        auth:

          type: OAuth2

        body:

          taskGroups:

            taskSpec:

              computeResource:

                cpuMilli: 4000

                memoryMib: 32000

              runnables:

                - container:

                    imageUri: ${imageUri}

                  environment:

                    variables:

                      BUCKET: ${bucket}

                      FILE: ${file}

            taskCount: 1

            parallelism: 1

          logsPolicy:

            destination: CLOUD_LOGGING

      result: createAndRunBatchJobResponse


워크플로 정의를 시작할 때 버킷과 파일 이름(내에서 환경 변수로 사용하는 항목)을 가져오는 데 사용할 워크플로 트리거(파일 업로드)에서 전송된 이벤트를 사용하도록 params 키워드를 설정합니다. main.py 파일 ).

다음으로 초기화 단계에서 GCP 프로젝트 ID를 가져옵니다. Batch API, Batch API URL, 빌드하고 Artifact Registry 에 푸시 하는 Docker 이미지의 URI 와 함께 배치 작업이 배포될 지역을 설정합니다 . 배치 작업 ID.

extract_bucket_and_file 단계 내 에서 수신된 이벤트에서 버킷 이름과 파일 이름을 추출합니다. 이 작업을 완료하면 이제 Batch 작업을 정의할 준비가 되었습니다.

초기화 단계에서 정의한 Batch API URL 에 POST 요청을 전송하여 배치 작업에 대한 정의를 시작합니다 . 다음은 작업에 대한 컴퓨팅 리소스를 정의하는 것입니다. 이 경우에는 4개의 CPU와 32GB의 메모리를 요청합니다. 마지막으로 Batch 작업에 실행할 컨테이너를 알려야 하며 초기화 단계에서 정의한 imageUri 를 제공하여 이를 수행합니다. 이벤트에서 추출한 버킷과 파일 이름을 환경 변수로 이미지에 설정한 다음 main.py 파일 내에서 사용합니다. 이것으로 워크플로가 준비되었습니다.

마지막으로 구현을 테스트할 수 있는 단계에 도달했습니다. 모든 것이 예상대로 작동하면 "처리되지 않은" 버킷에 파일을 업로드해야 워크플로가 실행되고 워크 플로 가 새 Batch 작업을 생성합니다. Batch 작업은 업로드된 파일을 다운로드해야 합니다.

GCP 에서 "처리되지 않은" 버킷으로 이동하고 선택한 파일을 업로드합니다. 그런 다음 Workflow 대시보드로 이동하여 Workflow 가 실행되었는지 확인합니다. 모든 작업을 올바르게 수행했다면 성공 상태여야 합니다.

다음 단계는 Batch 작업 대시보드로 이동하는 것입니다. 여기에서 Batch 작업이 생성된 것을 볼 수 있습니다. 몇 분 후 Batch 작업이 실행되기 시작하고 매우 빠르게 성공 상태로 들어갑니다( Python 스크립트는 정말 간단합니다).

이제 Batch 작업 에 대한 로그를 열고 Batch 작업이 "처리되지 않은" 스토리지 버킷에 업로드한 파일을 다운로드했음을 확인할 수 있습니다. 


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

0 0

Data Chef.

datachef00@gmail.com

ⓒ 2023 Data Chef.

Hosting by I'M Datachef

Data Chef.
e-Mail

datachef00@gmail.com


Seoul, Korea  ㅣ  Biz License 000-00-00000  ㅣ Hosting by Datachef.