Kubernetes Engine에서 Spark를 사용하여 BigQuery에서 데이터 처리

이 가이드에서는 BigQuery를 사용하여 데이터를 저장하고 Google Kubernetes Engine(GKE)에서 Spark를 사용하여 해당 데이터를 처리하는 데이터 파이프라인을 만들고 실행하는 방법을 보여줍니다. 이 파이프라인은 GKE에서 컴퓨팅 인프라를 표준화하고 기존 워크플로를 포팅할 방법을 찾고 있는 팀에게 유용합니다. 대부분의 팀에게 Spark 애플리케이션을 실행하는 데 가장 쉽고 확장성이 높은 방법은 Cloud Dataproc에서 Spark를 실행하는 것입니다. 이 가이드는 공개 BigQuery 데이터세트인 GitHub 데이터를 평가하여 기여도가 가장 큰 프로젝트를 찾습니다. 이 가이드에서는 사용자가 GKE 및 Apache Spark에 익숙하다고 가정합니다. 다음 다이어그램은 이 가이드에서 사용할 대략적인 아키텍처를 보여줍니다.

아키텍처 다이어그램

GitHub의 많은 프로젝트가 Go로 작성되었지만 도움이 필요한 프로젝트나 코드베이스가 가장 많이 필요한 부분을 참여자에게 알려주는 지표는 거의 없습니다.

이 가이드에서는 프로젝트 참여 필요 여부를 알기 위해 다음 지표를 사용합니다.

  • 미해결 문제의 수
  • 참여자의 수
  • 프로젝트의 패키지를 다른 프로젝트에서 가져온 횟수
  • FIXME 또는 TODO 주석의 빈도.

다음 다이어그램에서는 Spark 애플리케이션의 파이프라인을 볼 수 있습니다.

Spark 애플리케이션 파이프라인

목표

  • Spark 애플리케이션을 실행하기 위한 Kubernetes Engine 클러스터를 만듭니다.
  • Kubernetes Engine에 Spark 애플리케이션을 배포합니다.
  • Spark 애플리케이션에서 BigQuery 테이블을 쿼리하고 작성합니다.
  • BigQuery를 사용하여 결과를 분석합니다.

비용

이 가이드에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

가격 계산기를 사용하면 예상 사용량을 토대로 예상 비용을 산출할 수 있습니다. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  3. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. Kubernetes Engine and BigQuery API를 사용 설정합니다.

    API 사용 설정

환경 설정

이 섹션에서는 가이드를 완료하는 데 필요한 프로젝트 설정을 구성합니다.

Cloud Shell 인스턴스 시작

Cloud Shell 열기

Cloud Shell의 나머지 가이드로 진행합니다.

파이프라인 수동 실행

다음 단계에서는 BigQuery가 [bigquery-public-data:github_repos.files]의 하위 집합인 sample_files 테이블에서 확장자가 .go인 모든 파일을 추출하게 하여 파이프라인을 시작합니다. 데이터의 하위 집합을 사용하면 비용 효율적인 실험을 할 수 있습니다.

  1. Cloud Shell에서 중간 쿼리 결과를 저장하기 위해 다음 명령어를 실행하여 BigQuery에서 새 데이터세트 및 새 테이블을 만듭니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq mk --project_id $PROJECT spark_on_k8s_manual
    bq mk --project_id $PROJECT spark_on_k8s_manual.go_files
    
  2. GitHub 저장소 데이터세트에서 Go 파일의 샘플을 보고 --destination_table 옵션을 사용하여 파일을 중간 테이블에 저장합니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT --replace \
             --destination_table spark_on_k8s_manual.go_files \
        'SELECT id, repo_name, path FROM
    [bigquery-public-data:github_repos.sample_files]
         WHERE RIGHT(path, 3) = ".go"'
    

    파일 경로가 출처가 된 저장소와 함께 나열되어야 합니다. 예를 들면 다음과 같습니다.

    Waiting on bqjob_r311c807f17003279_0000015fb8007c47_1 ... (0s) Current status: DONE
    +------------------------------------------+------------------+-------------------------+
    |                    id                    |    repo_name     |          path           |
    +------------------------------------------+------------------+-------------------------+
    | 31a4559c1e636e | mandelsoft/spiff | spiff++/spiff.go        |
    | 15f7611dd21a89 | bep/gr           | examples/router/main.go |
    | 15cbb0b0f096a2 | knq/xo           | internal/fkmode.go      |
    +------------------------------------------+------------------+-------------------------+
    

    확인된 모든 Go 파일 목록이 spark_on_k8s_manual.go_files 테이블에 저장됩니다.

  3. 다음 쿼리를 실행하여 각 파일의 처음 10자를 표시합니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    bq query --project_id $PROJECT 'SELECT sample_repo_name as
    repo_name, SUBSTR(content, 0, 10) FROM
    [bigquery-public-data:github_repos.sample_contents] WHERE id IN
    (SELECT id FROM spark_on_k8s_manual.go_files)'
    

Kubernetes에서 Spark로 파이프라인 실행

다음으로 spark-bigquery 커넥터를 사용하여 BigQuery에 대해 직접 SQL 쿼리를 실행하는 Spark 애플리케이션과 비슷한 절차를 자동화합니다. 그런 다음 애플리케이션은 Spark SQL 및 DataFrames API를 사용하여 결과를 조작하고 BigQuery에 저장합니다.

Kubernetes Engine 클러스터 만들기

Spark와 샘플 애플리케이션을 배포하려면 다음 명령을 실행하여 Kubernetes Engine 클러스터를 만듭니다.

gcloud config set compute/zone us-central1-f
gcloud container clusters create spark-on-gke --machine-type n1-standard-2

샘플 코드 다운로드

샘플 애플리케이션 저장소를 복제합니다.

git clone https://github.com/GoogleCloudPlatform/spark-on-k8s-gcp-examples.git
cd spark-on-k8s-gcp-examples/github-insights

ID 및 액세스 관리 구성

BigQuery에 Spark 액세스 권한을 부여하려면 ID 및 액세스 관리 (IAM) 서비스 계정을 만들어야 합니다.

  1. 서비스 계정을 만듭니다.

    gcloud iam service-accounts create spark-bq --display-name spark-bq
    
  2. 나중에 명령어에 사용될 환경 변수에 서비스 계정 이메일 주소와 현재 프로젝트 ID를 저장합니다.

    export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:spark-bq" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
    
  3. 샘플 애플리케이션은 BigQuery 데이터세트와 테이블을 생성 및 조작하고 Cloud Storage에서 아티팩트를 제거해야 합니다. bigquery.dataOwner, bigQuery.jobUser, storage.admin 역할을 서비스 계정에 결합합니다.

    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/storage.admin
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.dataOwner
    gcloud projects add-iam-policy-binding $PROJECT --member serviceAccount:$SA_EMAIL --role roles/bigquery.jobUser
    
  4. 서비스 계정 JSON 키를 다운로드하여 Kubernetes 비밀번호에 저장합니다. Spark 드라이버 및 실행자는 이 비밀번호를 사용하여 BigQuery에 인증합니다.

    gcloud iam service-accounts keys create spark-sa.json --iam-account $SA_EMAIL
    kubectl create secret generic spark-sa --from-file=spark-sa.json
    
  5. Kubernetes 클러스터에서 작업을 시작할 수 있도록 Spark에 대한 사용 권한을 추가합니다.

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default spark-admin
    

Spark 애플리케이션 구성 및 실행

이제 Spark를 다운로드하여 설치하고 구성하여 Kubernetes Engine 클러스터에서 샘플 Spark 애플리케이션을 실행합니다.

  1. 샘플 애플리케이션의 빌드 프로세스를 관리하는 데 사용하는 Maven을 설치합니다.

    sudo apt-get install -y maven
  2. 샘플 애플리케이션 jar을 빌드합니다.

    mvn clean package
  3. 애플리케이션 jar과 Spark 파이프라인의 결과를 저장하는 Cloud Storage 버킷을 만듭니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-spark-on-k8s
    
  4. Cloud Storage 버킷에 애플리케이션 jar을 업로드합니다.

    gsutil cp target/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
                   gs://$PROJECT-spark-on-k8s/jars/
    
  5. 새 BigQuery 데이터세트를 만듭니다.

    bq mk --project_id $PROJECT spark_on_k8s
  6. 공식 Spark 2.3 배포판을 다운로드하고 압축을 풉니다.

    wget https://archive.apache.org/dist/spark/spark-2.3.0/spark-2.3.0-bin-hadoop2.7.tgz
    tar xvf spark-2.3.0-bin-hadoop2.7.tgz
    cd spark-2.3.0-bin-hadoop2.7
    
  7. 프로젝트별 정보가 포함된 속성 파일을 만들어 Spark 애플리케이션을 구성합니다.

    cat > properties << EOF
    spark.app.name  github-insights
    spark.kubernetes.namespace default
    spark.kubernetes.driverEnv.GCS_PROJECT_ID $PROJECT
    spark.kubernetes.driverEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.kubernetes.container.image gcr.io/cloud-solutions-images/spark:v2.3.0-gcs
    spark.kubernetes.driver.secrets.spark-sa  /mnt/secrets
    spark.kubernetes.executor.secrets.spark-sa /mnt/secrets
    spark.driver.cores 0.1
    spark.executor.instances 3
    spark.executor.cores 1
    spark.executor.memory 512m
    spark.executorEnv.GCS_PROJECT_ID    $PROJECT
    spark.executorEnv.GOOGLE_APPLICATION_CREDENTIALS /mnt/secrets/spark-sa.json
    spark.hadoop.google.cloud.auth.service.account.enable true
    spark.hadoop.google.cloud.auth.service.account.json.keyfile /mnt/secrets/spark-sa.json
    spark.hadoop.fs.gs.project.id $PROJECT
    EOF
    
  8. 다음 명령을 사용하여 샘플 GitHub 데이터세트에서 Spark 애플리케이션을 실행합니다.

    export KUBERNETES_MASTER_IP=$(gcloud container clusters list --filter name=spark-on-gke --format='value(MASTER_IP)')
    bin/spark-submit \
    --properties-file properties \
    --deploy-mode cluster \
    --class spark.bigquery.example.github.NeedingHelpGoPackageFinder \
    --master k8s://https://$KUBERNETES_MASTER_IP:443 \
    --jars http://central.maven.org/maven2/com/databricks/spark-avro_2.11/4.0.0/spark-avro_2.11-4.0.0.jar \
    gs://$PROJECT-spark-on-k8s/jars/github-insights-1.0-SNAPSHOT-jar-with-dependencies.jar \
    $PROJECT spark_on_k8s $PROJECT-spark-on-k8s --usesample
    
  9. Cloud Shell 세션 추가 버튼을 클릭하여 새 Cloud Shell 세션을 엽니다.

    Cloud Shell 세션 추가 버튼

  10. 새 Cloud Shell 세션에서 다음 명령어로 드라이버 포드의 로그를 확인하여 애플리케이션의 진행 상태를 추적합니다. 애플리케이션을 실행하는 데 약 5분이 소요됩니다.

    kubectl logs -l spark-role=driver
  11. 애플리케이션 실행이 끝나면 다음 명령어를 실행하여 가장 많이 사용되는 패키지 10개를 확인합니다.

    bq query "SELECT * FROM spark_on_k8s.popular_go_packages
    ORDER BY popularity DESC LIMIT 10"
    

8단계에서 --usesample 옵션을 제거하여 GitHub 데이터세트의 전체 테이블 세트에서 동일한 파이프라인을 실행할 수 있습니다. 전체 데이터세트의 크기는 샘플 데이터세트의 크기보다 훨씬 크기 때문에 합리적인 시간 내에 파이프라인을 완료하기 위해 더 큰 클러스터가 필요할 수 있습니다.

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

튜토리얼을 완료한 후에는 만든 리소스를 삭제하여 할당량 사용을 중지하고 요금이 청구되지 않도록 할 수 있습니다. 다음 섹션은 이러한 리소스를 삭제하거나 사용 중지하는 방법을 설명합니다.

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 가이드에서 만든 프로젝트를 삭제하는 것입니다.

프로젝트를 삭제하는 방법은 다음과 같습니다.

  1. Cloud Console에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

다음 단계

  • BigQuery 및 Dataproc과 함께 Spark를 사용하는 또 다른 예 살펴보기
  • 머신러닝에 Cloud Dataproc, BigQuery, Apache Spark ML을 사용하는 가이드 살펴보기

  • Google Cloud에 대한 참조 아키텍처, 다이어그램, 가이드, 권장사항을 살펴보세요. Cloud 아키텍처 센터 살펴보기