Utilisation de l'accélérateur RAPIDS pour Apache Spark avec Amazon EMR on EKS - Amazon EMR

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation de l'accélérateur RAPIDS pour Apache Spark avec Amazon EMR on EKS

Avec Amazon EMR on EKS, vous pouvez exécuter des tâches pour l'accélérateur Nvidia RAPIDS pour Apache Spark. Ce didacticiel explique comment exécuter des tâches Spark à l'aide de RAPIDS sur des types d'instance EC2 à unité de traitement graphique (GPU). Le didacticiel utilise les versions suivantes :

  • Amazon EMR on EKS en version 6.9.0 et ultérieure

  • Apache Spark 3.x

Vous pouvez accélérer Spark avec des types d'instances Amazon EC2 à GPU en utilisant le plug-in Nvidia Accélérateur RAPIDS pour Apache Spark. Lorsque vous utilisez ces technologies ensemble, vous accélérez vos pipelines de science des données sans avoir à modifier le code. Cela permet de réduire le temps d'exécution nécessaire au traitement des données et à l'apprentissage des modèles. En accomplissant plus de tâches en moins de temps, vous dépensez moins sur le coût de l'infrastructure.

Avant de commencer, assurez-vous de disposer des ressources ci-dessous.

  • Cluster virtuel Amazon EMR on EKS

  • Cluster Amazon EKS avec un groupe de nœuds équipés de GPU

Le cluster virtuel Amazon EKS est un descripteur enregistré dans l'espace de noms Kubernetes d'un cluster Amazon EKS, et est géré par Amazon EMR on EKS. Le descripteur permet à Amazon EMR d'utiliser l'espace de noms Kubernetes comme destination pour exécuter des tâches. Pour plus d'informations sur la configuration d'un cluster virtuel, consultez Configuration d'Amazon EMR sur EKS dans ce guide.

Vous devez configurer le cluster virtuel Amazon EKS avec un groupe de nœuds doté d'instances GPU. Vous devez configurer les nœuds avec un plug-in de périphérique Nvidia. Consultez la rubrique Groupes de nœuds gérés pour en savoir plus.

Pour configurer votre cluster Amazon EKS afin d'ajouter des groupes de nœuds équipés de GPU, procédez comme suit :

Ajout de groupes de nœuds équipés de GPU
  1. Créez un groupe de nœuds équipés de GPU à l'aide de la commande create-nodegroup suivante. Assurez-vous de remplacer par les paramètres corrects votre cluster Amazon EKS. Utilisez type d'instance compatible avec RAPIDS pour Spark, comme P4, P3, G5 ou G4dn.

    aws eks create-nodegroup \ --cluster-name EKS_CLUSTER_NAME \ --nodegroup-name NODEGROUP_NAME \ --scaling-config minSize=0,maxSize=5,desiredSize=2 CHOOSE_APPROPRIATELY \ --ami-type AL2_x86_64_GPU \ --node-role NODE_ROLE \ --subnets SUBNETS_SPACE_DELIMITED \ --remote-access ec2SshKey= SSH_KEY \ --instance-types GPU_INSTANCE_TYPE \ --disk-size DISK_SIZE \ --region AWS_REGION
  2. Installez le plug-in de périphérique Nvidia dans votre cluster pour afficher le nombre de GPU sur chaque nœud de votre cluster et pour exécuter des conteneurs équipés de GPU dans votre cluster. Exécutez le code suivant pour installer le plug-in :

    kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.9.0/nvidia-device-plugin.yml
  3. Pour valider le nombre de GPU disponibles sur chaque nœud de votre cluster, exécutez la commande suivante :

    kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"
Exécution d'une tâche RAPIDS pour Spark
  1. Soumettez une tâche RAPIDS pour Spark à votre cluster Amazon EMR on EKS. Le code suivant montre un exemple de commande permettant de démarrer la tâche. La première fois que vous exécutez la tâche, le téléchargement de l'image et sa mise en cache sur le nœud peuvent prendre quelques minutes.

    aws emr-containers start-job-run \ --virtual-cluster-id VIRTUAL_CLUSTER_ID \ --execution-role-arn JOB_EXECUTION_ROLE \ --release-label emr-6.9.0-spark-rapids-latest \ --job-driver '{"sparkSubmitJobDriver": {"entryPoint": "local:///usr/lib/spark/examples/jars/spark-examples.jar","entryPointArguments": ["10000"], "sparkSubmitParameters":"--class org.apache.spark.examples.SparkPi "}}' \ ---configuration-overrides '{"applicationConfiguration": [{"classification": "spark-defaults","properties": {"spark.executor.instances": "2","spark.executor.memory": "2G"}}],"monitoringConfiguration": {"cloudWatchMonitoringConfiguration": {"logGroupName": "LOG_GROUP _NAME"},"s3MonitoringConfiguration": {"logUri": "LOG_GROUP_STREAM"}}}'
  2. Pour vérifier que l'accélérateur RAPIDS pour Spark est activé, consultez les journaux du pilote Spark. Ces journaux sont stockés soit dans CloudWatch, soit dans l'emplacement S3 que vous indiquez lorsque vous exécutez la commande start-job-run. L'exemple suivant montre généralement à quoi ressemblent les lignes de journal :

    22/11/15 00:12:44 INFO RapidsPluginUtils: RAPIDS Accelerator build: {version=22.08.0-amzn-0, user=release, url=, date=2022-11-03T03:32:45Z, revision=, cudf_version=22.08.0, branch=}
    22/11/15 00:12:44 INFO RapidsPluginUtils: RAPIDS Accelerator JNI build: {version=22.08.0, user=, url=https://github.com/NVIDIA/spark-rapids-jni.git, date=2022-08-18T04:14:34Z, revision=a1b23cd_sample, branch=HEAD}
    22/11/15 00:12:44 INFO RapidsPluginUtils: cudf build: {version=22.08.0, user=, url=https://github.com/rapidsai/cudf.git, date=2022-08-18T04:14:34Z, revision=a1b23ce_sample, branch=HEAD}
    22/11/15 00:12:44 WARN RapidsPluginUtils: RAPIDS Accelerator 22.08.0-amzn-0 using cudf 22.08.0.
    22/11/15 00:12:44 WARN RapidsPluginUtils: spark.rapids.sql.multiThreadedRead.numThreads is set to 20.
    22/11/15 00:12:44 WARN RapidsPluginUtils: RAPIDS Accelerator is enabled, to disable GPU support set `spark.rapids.sql.enabled` to false.
    22/11/15 00:12:44 WARN RapidsPluginUtils: spark.rapids.sql.explain is set to `NOT_ON_GPU`. Set it to 'NONE' to suppress the diagnostics logging about the query placement on the GPU.
  3. Pour voir les opérations qui seront exécutées sur une GPU, effectuez les étapes suivantes pour activer la journalisation supplémentaire. Notez la configuration « spark.rapids.sql.explain : ALL ».

    aws emr-containers start-job-run \ --virtual-cluster-id VIRTUAL_CLUSTER_ID \ --execution-role-arn JOB_EXECUTION_ROLE \ --release-label emr-6.9.0-spark-rapids-latest \ --job-driver '{"sparkSubmitJobDriver": {"entryPoint": "local:///usr/lib/spark/examples/jars/spark-examples.jar","entryPointArguments": ["10000"], "sparkSubmitParameters":"--class org.apache.spark.examples.SparkPi "}}' \ ---configuration-overrides '{"applicationConfiguration": [{"classification": "spark-defaults","properties": {"spark.rapids.sql.explain":"ALL","spark.executor.instances": "2","spark.executor.memory": "2G"}}],"monitoringConfiguration": {"cloudWatchMonitoringConfiguration": {"logGroupName": "LOG_GROUP_NAME"},"s3MonitoringConfiguration": {"logUri": "LOG_GROUP_STREAM"}}}'

    La commande précédente est un exemple de tâche utilisant la GPU. Son résultat ressemblerait à l'exemple ci-dessous. Reportez-vous à cette clé pour mieux comprendre le résultat :

    • * : marque une opération fonctionnant sur une GPU

    • ! : marque une opération qui ne peut pas être exécutée sur une GPU

    • @ : marque une opération fonctionnant sur un GPU, mais qui ne sera pas exécutée parce qu'elle fait partie d'un plan qui ne peut pas être exécuté sur une GPU

     22/11/15 01:22:58 INFO GpuOverrides: Plan conversion to the GPU took 118.64 ms
     22/11/15 01:22:58 INFO GpuOverrides: Plan conversion to the GPU took 4.20 ms
     22/11/15 01:22:58 INFO GpuOverrides: GPU plan transition optimization took 8.37 ms
     22/11/15 01:22:59 WARN GpuOverrides:
        *Exec <ProjectExec> will run on GPU
          *Expression <Alias> substring(cast(date#149 as string), 0, 7) AS month#310 will run on GPU
            *Expression <Substring> substring(cast(date#149 as string), 0, 7) will run on GPU
              *Expression <Cast> cast(date#149 as string) will run on GPU
          *Exec <SortExec> will run on GPU
            *Expression <SortOrder> date#149 ASC NULLS FIRST will run on GPU
            *Exec <ShuffleExchangeExec> will run on GPU
              *Partitioning <RangePartitioning> will run on GPU
                *Expression <SortOrder> date#149 ASC NULLS FIRST will run on GPU
              *Exec <UnionExec> will run on GPU
                !Exec <ProjectExec> cannot run on GPU because not all expressions can be replaced
                  @Expression <AttributeReference> customerID#0 could run on GPU
                  @Expression <Alias> Charge AS kind#126 could run on GPU
                    @Expression <Literal> Charge could run on GPU
                  @Expression <AttributeReference> value#129 could run on GPU
                  @Expression <Alias> add_months(2022-11-15, cast(-(cast(_we0#142 as bigint) + last_month#128L) as int)) AS date#149 could run on GPU
                    ! <AddMonths> add_months(2022-11-15, cast(-(cast(_we0#142 as bigint) + last_month#128L) as int)) cannot run on GPU because GPU does not currently support the operator class org.apache.spark.sql.catalyst.expressions.AddMonths
                      @Expression <Literal> 2022-11-15 could run on GPU
                      @Expression <Cast> cast(-(cast(_we0#142 as bigint) + last_month#128L) as int) could run on GPU
                        @Expression <UnaryMinus> -(cast(_we0#142 as bigint) + last_month#128L) could run on GPU
                          @Expression <Add> (cast(_we0#142 as bigint) + last_month#128L) could run on GPU
                            @Expression <Cast> cast(_we0#142 as bigint) could run on GPU
                              @Expression <AttributeReference> _we0#142 could run on GPU
                            @Expression <AttributeReference> last_month#128L could run on GPU