Ma tâche Spark ou Hive sur Amazon EMR échoue avec une exception AmazonS3Exception HTTP 503 « Slow Down » (Ralentir)

Date de la dernière mise à jour : 20/04/2020

Ma tâche Apache Spark ou Apache Hive sur Amazon EMR échoue avec une exception AmazonS3 HTTP 503 « Slow Down » (Ralentir) similaire à celle-ci :

java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Slow Down (Service: Amazon S3; Status Code: 503; Error Code: 503 Slow Down; Request ID: 2E8B8866BFF00645; S3 Extended Request ID: oGSeRdT4xSKtyZAcUe53LgUf1+I18dNXpL2+qZhFWhuciNOYpxX81bpFiTw2gum43GcOHR+UlJE=), S3 Extended Request ID: oGSeRdT4xSKtyZAcUe53LgUf1+I18dNXpL2+qZhFWhuciNOYpxX81bpFiTw2gum43GcOHR+UlJE=

Brève description

Cette erreur se produit lorsque vous dépassez le taux de requêtes Amazon Simple Storage Service (Amazon S3). Le taux de requêtes est de 3 500 demandes PUT/COPY/POST/DELETE et 5 500 demandes GET/HEAD par seconde et par préfixe dans un compartiment.

Vous pouvez résoudre ce problème de trois façons :

  • Ajouter d'autres préfixes au compartiment S3.
  • Réduire le nombre de requêtes Amazon S3.
  • Augmenter la limite de relance du système de fichiers EMR (EMRFS).

Solution

Avant de pouvoir identifier le problème lié à un trop grand nombre de requêtes, configurez d'abord les métriques de demande Amazon CloudWatch.

Configurer les métriques de demande CloudWatch

Pour surveiller les demandes Amazon S3, activez les métriques de demande CloudWatch pour le compartiment. Ensuite, définissez un filtre pour le préfixe. Pour obtenir la liste des métriques utiles à surveiller, consultez Métriques de demande Amazon S3 CloudWatch.

Une fois que vous avez activé les métriques, utilisez les données des métriques pour déterminer celle des solutions suivantes qui vous convient le mieux à votre cas d'utilisation.

Ajouter d'autres préfixes au compartiment S3

Le nombre de préfixes dans un compartiment est illimité. Le taux de demandes s'applique à chaque préfixe et non au compartiment. Par exemple, si vous créez trois préfixes dans un compartiment comme celui-ci :

  • s3://awsexamplebucket/images
  • s3://awsexamplebucket/videos
  • s3://awsexamplebucket/documents

Vous pouvez ensuite effectuer 10 500 demandes d'écriture ou 16 500 demandes de lecture par seconde dans ce compartiment.

Réduire le nombre de requêtes Amazon S3

  • Si plusieurs tâches simultanées (Spark, Apache Hive ou s3-dist-cp) lisent ou écrivent sur le même préfixe Amazon S3 : réduisez le nombre de tâches simultanées. Commencez par les tâches les plus volumineuses en lecture/écriture. Si vous avez configuré l'accès entre comptes pour Amazon S3, n'oubliez pas que d'autres comptes peuvent également soumettre des tâches au préfixe.
  • Si l'erreur se produit lorsque la tâche tente d'écrire dans le compartiment de destination : réduisez le parallélisme des tâches. Par exemple, utilisez les opérations Spark .coalesce () ou .repartition() pour réduire le nombre de partitions de sortie Spark avant d'écrire dans Amazon S3. Vous pouvez également réduire le nombre de cœurs par programme d'exécution ou le nombre de programmes d'exécution.
  • Si l'erreur se produit lorsque la tâche tente de lire à partir du compartiment source : réduisez le nombre de fichiers pour réduire le nombre de requêtes Amazon S3. Par exemple, utilisez s3-dist-cp pour fusionner un grand nombre de petits fichiers en un plus petit nombre de fichiers volumineux.

Augmenter la limite de relance EMRFS

Par défaut, la limite de relance EMRFS est définie sur 4. Vous pouvez augmenter la limite de nouvelles tentatives sur un nouveau cluster, sur un cluster en cours d'exécution ou lors de l'exécution de l'application.

Pour augmenter la limite de relance sur un nouveau cluster sans cohérence EMRFS, ajoutez un objet de configuration similaire à celui ci-dessous lorsque vous lancez le cluster.

[
    {
      "Classification": "emrfs-site",
      "Properties": {
        "fs.s3.maxRetries": "20"
      }
    }
]

Pour lancer un nouveau cluster avec une cohérence EMRFS et une limite de nouvelle tentative plus élevée :

Au lieu d'activer EMRFS consistent view (vue cohérente d’EMRFS) lors de l'Étape 3 : Paramètres généraux du cluster, sous Additional Options (Options supplémentaires), ajoutez un objet de configuration similaire à ce qui suit lorsque vous lancez le cluster. Cette configuration spécifie toutes les propriétés requises pour la vue cohérente d'EMRFS et augmente la limite de nouvelle tentative à 20.

[
    {
      "Classification": "emrfs-site",
      "Properties": {
        "fs.s3.maxRetries": "20",
        "fs.s3.consistent.retryPeriodSeconds": "10",
        "fs.s3.consistent": "true",
        "fs.s3.consistent.retryCount": "5",
        "fs.s3.consistent.metadata.tableName": "EmrFSMetadata"
      }
    }
]

Une fois le cluster lancé, les applications Spark et Hive utilisent la nouvelle limite.

Pour augmenter la limite de relance sur un cluster en cours d'exécution :

1.    Ouvrez la Amazon EMR console.

2.    Dans la liste des clusters, choisissez le cluster actif que vous souhaitez reconfigurer sous Name (Nom).

3.    Ouvrez la page des détails du cluster et choisissez l'onglet Configurations.

4.    Dans la liste déroulante Filter(Filtrer), sélectionnez le groupe d'instances que vous souhaitez reconfigurer.

5.    Dans le menu déroulant Reconfigure (Reconfigurer), choisissez Edit in table (Modifier dans la table).

6.    Dans le tableau de classification de configuration, choisissez Add configuration (Ajouter une configuration), puis entrez ce qui suit :

Pour Classification : emrfs-site
Pour Property (Propriété) : fs.s3.maxRetries
Pour Value (Valeur) : la nouvelle valeur de la limite de nouvelle tentative (par exemple, 20)

7.    Sélectionnez Apply this configuration to all active instance groups (Appliquer cette configuration à tous les groupes d'instances actifs), puis choisissez Save changes (Enregistrer les modifications).

Une fois la configuration déployée, les applications Spark et Hive utilisent la nouvelle limite.

Pour augmenter la limite de nouvelles tentatives lors de l'exécution :

Voici un exemple de session shell Spark qui augmente la limite de nouvelles tentatives lors de l'exécution :

spark> sc.hadoopConfiguration.set("fs.s3.maxRetries", "20")
spark> val source_df = spark.read.csv("s3://awsexamplebucket/data/")
spark> source_df.write.save("s3://awsexamplebucket2/output/")

Voici un exemple de la façon d'augmenter la limite de nouvelle tentative lors de l'exécution d'une application Hive :

hive> set fs.s3.maxRetries=20;
hive> select ....