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

Date de la dernière mise à jour : 17/05/2022

Ma tâche Apache Spark ou Apache Hive sur Amazon EMR échoue avec une exception AmazonS3Exception HTTP 503 « Slow Down » (Ralentir) similaire à ce qui suit :

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 le taux de requête d'Amazon Simple Storage Service (Amazon S3) pour votre application dépasse les taux généralement soutenus de plus de 5 000 requêtes par seconde, et qu'Amazon S3 optimise en interne les performances.

Pour améliorer le taux de réussite de vos requêtes lorsque vous accédez aux données S3 à l'aide d'Amazon EMR, essayez les approches suivantes :

  • Modifiez la stratégie de nouvelle tentative pour les requêtes S3.
  • Ajustez le nombre de requêtes S3 simultanées.

Solution

Pour aider à identifier le problème du trop grand nombre de requêtes, une bonne pratique consiste à configurer les métriques de requête Amazon CloudWatch pour le compartiment S3. Vous pouvez déterminer la solution qui convient le mieux à votre cas d'utilisation en fonction de ces métriques CloudWatch.

Configurer les métriques de requête 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 la section Surveillance des métriques avec Amazon CloudWatch.

Modifier la stratégie de nouvelle tentative pour les demandes S3

Par défaut, EMRFS utilise une stratégie de backoff exponentielle pour relancer les requêtes vers Amazon S3. La limite de nouvelle tentative par défaut d'EMRFS est de 15. Cependant, 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 tentatives, modifiez la valeur du paramètre fs.s3.maxRetries. Si vous définissez une valeur très élevée pour ce paramètre, la durée de la tâche risque d'être plus longue. Essayez de définir ce paramètre à une valeur élevée (par exemple, 20), surveillez la durée des tâches, puis ajustez ce paramètre en fonction de votre cas d'utilisation.

Pour un nouveau cluster, vous pouvez ajouter un objet de configuration similaire à ce qui suit lorsque vous lancez le cluster :

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

Après le lancement du cluster, les applications Spark et Hive qui s'exécutent sur Amazon EMR utilisent la nouvelle limite.

Pour augmenter la limite de nouvelles tentatives sur un cluster en cours d'exécution, procédez comme suit :

1.    Ouvrez la console Amazon EMR.

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 à reconfigurer.

5.    Dans la liste déroulante Reconfigure (Reconfigurer) choisissez Edit in table (Modifier dans le tableau).

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).

8.    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 au moment de l'exécution, utilisez une session shell Spark similaire à ce qui suit :

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 nouvelles tentatives lors de l'exécution d'une application Hive :

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

Ajuster le nombre de requêtes S3 simultanées

  • Si vous avez plusieurs tâches (Spark, Apache Hive ou s-dist-cp) qui lisent et écrivent sur le même préfixe S3, vous pouvez ajuster la simultanéité. Commencez par les tâches les plus lourdes en lecture/écriture et diminuez leur simultanéité pour éviter un parallélisme excessif. Si vous avez configuré l'accès entre comptes pour Amazon S3, n'oubliez pas que d'autres comptes peuvent également envoyer des tâches au même préfixe.
  • Si vous voyez des erreurs lorsque la tâche tente d'écrire dans le compartiment de destination, réduisez le parallélisme d'écriture excessif. 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 vous constatez des erreurs lorsque la tâche tente de lire à partir du compartiment source, ajustez la taille des objets. Vous pouvez agréger des objets plus petits à des objets plus grands afin de réduire le nombre d'objets à lire par la tâche. Cela permet à vos tâches de lire des jeux de données avec moins de demandes de lecture. Par exemple, utilisez s3-dist-cp pour fusionner un grand nombre de petits fichiers en un plus petit nombre de fichiers volumineux.