Menggunakan YuniKorn sebagai penjadwal khusus untuk Apache Spark di Amazon EMR di EKS - Amazon EMR

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Menggunakan YuniKorn sebagai penjadwal khusus untuk Apache Spark di Amazon EMR di EKS

Dengan Amazon EMR di EKS, Anda dapat menggunakan operator Spark atau spark-submit untuk menjalankan pekerjaan Spark dengan penjadwal kustom Kubernetes. Tutorial ini mencakup cara menjalankan pekerjaan Spark dengan YuniKorn penjadwal pada antrian kustom dan penjadwalan geng.

Gambaran Umum

Apache YuniKorn dapat membantu mengelola penjadwalan Spark dengan penjadwalan sadar aplikasi sehingga Anda dapat memiliki kontrol yang baik pada kuota dan prioritas sumber daya. Dengan penjadwalan geng, YuniKorn jadwalkan aplikasi hanya jika permintaan sumber daya minimal untuk aplikasi dapat dipenuhi. Untuk informasi lebih lanjut, lihat Apa itu penjadwalan geng di situs YuniKorn dokumentasi Apache.

Buat klaster Anda dan siapkan YuniKorn

Gunakan langkah-langkah berikut untuk menerapkan klaster Amazon EKS. Anda dapat mengubah Wilayah AWS (region) dan Availability Zones (availabilityZones).

  1. Tentukan klaster Amazon EKS:

    cat <<EOF >eks-cluster.yaml --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: emr-eks-cluster region: eu-west-1 vpc: clusterEndpoints: publicAccess: true privateAccess: true iam: withOIDC: true nodeGroups: - name: spark-jobs labels: { app: spark } instanceType: m5.xlarge desiredCapacity: 2 minSize: 2 maxSize: 3 availabilityZones: ["eu-west-1a"] EOF
  2. Buat klaster:

    eksctl create cluster -f eks-cluster.yaml
  3. Buat namespace spark-job tempat Anda akan mengeksekusi pekerjaan Spark:

    kubectl create namespace spark-job
  4. Selanjutnya, buat role dan role binding Kubernetes. Ini diperlukan untuk akun layanan yang digunakan oleh pekerjaan Spark.

    1. Tentukan akun layanan, peran, dan pengikatan peran untuk pekerjaan Spark.

      cat <<EOF >emr-job-execution-rbac.yaml --- apiVersion: v1 kind: ServiceAccount metadata: name: spark-sa namespace: spark-job automountServiceAccountToken: false --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: spark-role namespace: spark-job rules: - apiGroups: ["", "batch","extensions"] resources: ["configmaps","serviceaccounts","events","pods","pods/exec","pods/log","pods/portforward","secrets","services","persistentvolumeclaims"] verbs: ["create","delete","get","list","patch","update","watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: spark-sa-rb namespace: spark-job roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: spark-role subjects: - kind: ServiceAccount name: spark-sa namespace: spark-job EOF
    2. Terapkan definisi role dan role binding Kubernetes dengan perintah berikut:

      kubectl apply -f emr-job-execution-rbac.yaml

Instal dan atur YuniKorn

  1. Gunakan perintah kubectl berikut untuk membuat namespace untuk men-deploy penjadwal yunikorn Yunikorn:

    kubectl create namespace yunikorn
  2. Untuk menginstal scheduler, jalankan perintah Helm berikut:

    helm repo add yunikorn https://apache.github.io/yunikorn-release
    helm repo update
    helm install yunikorn yunikorn/yunikorn --namespace yunikorn

Jalankan aplikasi Spark dengan YuniKorn scheduler dengan operator Spark

  1. Jika Anda belum melakukannya, selesaikan langkah-langkah di bagian berikut untuk menyiapkan:

    1. Buat klaster Anda dan siapkan YuniKorn

    2. Instal dan atur YuniKorn

    3. Menyiapkan operator Spark untuk Amazon EMR di EKS

    4. Instal operator Spark

      Sertakan argumen berikut saat Anda menjalankan helm install spark-operator-demo perintah:

      --set batchScheduler.enable=true --set webhook.enable=true
  2. Buat file SparkApplication definisispark-pi.yaml.

    Untuk digunakan YuniKorn sebagai penjadwal untuk pekerjaan Anda, Anda harus menambahkan anotasi dan label tertentu ke definisi aplikasi Anda. Anotasi dan label menentukan antrian untuk pekerjaan Anda dan strategi penjadwalan yang ingin Anda gunakan.

    Pada contoh berikut, anotasi schedulingPolicyParameters mengatur penjadwalan geng untuk aplikasi. Kemudian, contoh membuat grup tugas, atau “geng” tugas, untuk menentukan kapasitas minimum yang harus tersedia sebelum menjadwalkan Pod untuk memulai eksekusi pekerjaan. Dan akhirnya, itu menentukan dalam definisi kelompok tugas untuk menggunakan kelompok simpul dengan "app": "spark" label, seperti yang didefinisikan dalam Buat klaster Anda dan siapkan YuniKorn bagian.

    apiVersion: "sparkoperator.k8s.io/v1beta2" kind: SparkApplication metadata: name: spark-pi namespace: spark-job spec: type: Scala mode: cluster image: "895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.10.0:latest" imagePullPolicy: Always mainClass: org.apache.spark.examples.SparkPi mainApplicationFile: "local:///usr/lib/spark/examples/jars/spark-examples.jar" sparkVersion: "3.3.1" restartPolicy: type: Never volumes: - name: "test-volume" hostPath: path: "/tmp" type: Directory driver: cores: 1 coreLimit: "1200m" memory: "512m" labels: version: 3.3.1 annotations: yunikorn.apache.org/schedulingPolicyParameters: "placeholderTimeoutSeconds=30 gangSchedulingStyle=Hard" yunikorn.apache.org/task-group-name: "spark-driver" yunikorn.apache.org/task-groups: |- [{ "name": "spark-driver", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }, { "name": "spark-executor", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }] serviceAccount: spark-sa volumeMounts: - name: "test-volume" mountPath: "/tmp" executor: cores: 1 instances: 1 memory: "512m" labels: version: 3.3.1 annotations: yunikorn.apache.org/task-group-name: "spark-executor" volumeMounts: - name: "test-volume" mountPath: "/tmp"
  3. Kirim aplikasi Spark dengan perintah berikut. Ini juga menciptakan SparkApplication objek yang disebutspark-pi:

    kubectl apply -f spark-pi.yaml
  4. Periksa peristiwa untuk SparkApplication objek dengan perintah berikut:

    kubectl describe sparkapplication spark-pi --namespace spark-job

    Peristiwa Pod pertama akan menunjukkan bahwa YuniKorn telah menjadwalkan Pod:

    Type    Reason            Age   From                          Message
    ----    ------            ----  ----                          -------
    Normal Scheduling        3m12s yunikorn   spark-operator/org-apache-spark-examples-sparkpi-2a777a88b98b8a95-driver is queued and waiting for allocation
    Normal GangScheduling    3m12s yunikorn   Pod belongs to the taskGroup spark-driver, it will be scheduled as a gang member
    Normal Scheduled         3m10s yunikorn   Successfully assigned spark
    Normal PodBindSuccessful 3m10s yunikorn   Pod spark-operator/
    Normal TaskCompleted     2m3s  yunikorn   Task spark-operator/
    Normal Pulling           3m10s kubelet    Pulling

Jalankan aplikasi Spark dengan YuniKorn scheduler dengan spark-submit

  1. Pertama, selesaikan langkah-langkah di Menyiapkan spark-submit untuk Amazon EMR di EKS bagian ini.

  2. Tetapkan nilai untuk variabel lingkungan berikut:

    export SPARK_HOME=spark-home export MASTER_URL=k8s://Amazon-EKS-cluster-endpoint
  3. Kirimkan aplikasi Spark dengan perintah berikut:

    Pada contoh berikut, anotasi schedulingPolicyParameters mengatur penjadwalan geng untuk aplikasi. Kemudian, contoh membuat grup tugas, atau “geng” tugas, untuk menentukan kapasitas minimum yang harus tersedia sebelum menjadwalkan Pod untuk memulai eksekusi pekerjaan. Dan akhirnya, itu menentukan dalam definisi kelompok tugas untuk menggunakan kelompok simpul dengan "app": "spark" label, seperti yang didefinisikan dalam Buat klaster Anda dan siapkan YuniKorn bagian.

    $SPARK_HOME/bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master $MASTER_URL \ --conf spark.kubernetes.container.image=895885662937.dkr.ecr.us-west-2.amazonaws.com/spark/emr-6.10.0:latest \ --conf spark.kubernetes.authenticate.driver.serviceAccountName=spark-sa \ --deploy-mode cluster \ --conf spark.kubernetes.namespace=spark-job \ --conf spark.kubernetes.scheduler.name=yunikorn \ --conf spark.kubernetes.driver.annotation.yunikorn.apache.org/schedulingPolicyParameters="placeholderTimeoutSeconds=30 gangSchedulingStyle=Hard" \ --conf spark.kubernetes.driver.annotation.yunikorn.apache.org/task-group-name="spark-driver" \ --conf spark.kubernetes.executor.annotation.yunikorn.apache.org/task-group-name="spark-executor" \ --conf spark.kubernetes.driver.annotation.yunikorn.apache.org/task-groups='[{ "name": "spark-driver", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }, { "name": "spark-executor", "minMember": 1, "minResource": { "cpu": "1200m", "memory": "1Gi" }, "nodeSelector": { "app": "spark" } }]' \ local:///usr/lib/spark/examples/jars/spark-examples.jar 20
  4. Periksa peristiwa untuk SparkApplication objek dengan perintah berikut:

    kubectl describe pod spark-driver-pod --namespace spark-job

    Peristiwa Pod pertama akan menunjukkan bahwa YuniKorn telah menjadwalkan Pod:

    Type    Reason           Age   From                          Message
    ----    ------           ----  ----                          -------
    Normal Scheduling        3m12s yunikorn   spark-operator/org-apache-spark-examples-sparkpi-2a777a88b98b8a95-driver is queued and waiting for allocation
    Normal GangScheduling    3m12s yunikorn   Pod belongs to the taskGroup spark-driver, it will be scheduled as a gang member
    Normal Scheduled         3m10s yunikorn   Successfully assigned spark
    Normal PodBindSuccessful 3m10s yunikorn   Pod spark-operator/
    Normal TaskCompleted     2m3s  yunikorn   Task spark-operator/
    Normal Pulling           3m10s kubelet    Pulling