Amazon EMR (Elastic MapReduce) est un service géré facilitant l’exécution de frameworks Big Data tels que Spark, Hadoop, Hive ou Presto. L’AWS CLI offre une interface en ligne de commande complète pour orchestrer l’ensemble du cycle de vie des clusters, depuis leur création jusqu’à leur terminaison, en passantt par la configuration et la supervision.
Mise en place de l’environnement
Installez la CLI AWS et configurez vos identifiants :
pip install awscli
aws configure
Création rapide d’un cluster
Pour lancer un cluster minimal avec Spark et Hadoop :
aws emr create-cluster \
--release-label emr-6.10.0 \
--instance-type m5.large \
--instance-count 3 \
--use-default-roles \
--applications Name=Spark Name=Hadoop
Gestion du cycle de vie des clusters
Création avancée
Définissez des groupes d’instances maître, cœur et tâches :
aws emr create-cluster \
--name "Cluster-Analytique" \
--release-label emr-6.10.0 \
--applications Name=Hadoop Name=Spark Name=Hive \
--instance-groups \
InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m5.xlarge \
InstanceGroupType=CORE,InstanceCount=2,InstanceType=m5.2xlarge \
InstanceGroupType=TASK,InstanceCount=3,InstanceType=m5.2xlarge \
--use-default-roles \
--log-uri s3://mes-logs-emr/ \
--auto-terminate
Utilisez les flottes d’instances pour tirer parti des instances Spot et réduire les coûts :
aws emr create-cluster \
--release-label emr-6.10.0 \
--instance-fleets \
InstanceFleetType=MASTER,TargetOnDemandCapacity=1,InstanceTypeConfigs='[{InstanceType=m5.xlarge,WeightedCapacity=1}]' \
InstanceFleetType=CORE,TargetSpotCapacity=8,InstanceTypeConfigs='[{InstanceType=m5.2xlarge,BidPrice=0.4,WeightedCapacity=4},{InstanceType=r5.2xlarge,BidPrice=0.5,WeightedCapacity=4}]' \
--service-role EMR_DefaultRole \
--ec2-attributes InstanceProfile=EMR_EC2_DefaultRole,KeyName=ma-clef \
--log-uri s3://mes-logs-emr/ \
--enable-debugging
Personnalisation des applications
Créez un fichier mes-configurations.json :
[
{
"Classification": "spark-defaults",
"Properties": {
"spark.executor.memory": "4g",
"spark.executor.cores": "2",
"spark.driver.memory": "2g"
}
},
{
"Classification": "yarn-site",
"Properties": {
"yarn.nodemanager.resource.memory-mb": "16384",
"yarn.scheduler.maximum-allocation-mb": "16384"
}
}
]
Appliquez cette configuration lors de la créasion :
aws emr create-cluster \
--configurations file://mes-configurations.json \
--release-label emr-6.10.0 \
--instance-type m5.large \
--instance-count 3 \
--use-default-roles
Sécurité Kerberos
aws emr create-cluster \
--security-configuration MaConfigSecurite \
--kerberos-attributes Realm=EC2.INTERNAL,KdcAdminPassword=MonMotDePasse123 \
--release-label emr-6.10.0 \
--instance-type m5.large \
--instance-count 3
Supervision des clusters
Lister les clusters actifs :
aws emr list-clusters --active
Obtenir des informations détaillées :
aws emr describe-cluster --cluster-id j-XXXXXXXXXX
Lister les instances d’un groupe particulier :
aws emr list-instances --cluster-id j-XXXXXXXXXX --instance-group-types CORE
Gestion des étapes
Ajouter des traitements Spark et Hive :
aws emr add-steps \
--cluster-id j-XXXXXXXXXX \
--steps \
Type=Spark,Name="ETL-Spark",ActionOnFailure=CONTINUE,Args=[--class,com.exemple.Traitement,--master,yarn,--deploy-mode,cluster,s3://mon-bucket/jobs/traitement.jar,s3://donnees-entree/,s3://resultats/] \
Type=Hive,Name="Analyse-Hive",ActionOnFailure=CONTINUE,Args=[-f,s3://mon-bucket/scripts/analyse.hql,-d,INPUT=s3://donnees-entree/,-d,OUTPUT=s3://resultats/]
Vérifier l’état d’une étape :
aws emr describe-step --cluster-id j-XXXXXXXXXX --step-id s-XXXXXXXXXX
Arrêt du cluster
aws emr terminate-clusters --cluster-ids j-XXXXXXXXXX
Fonctionnalités avancées
Mise à l’échelle automatique
aws emr create-cluster \
--release-label emr-6.10.0 \
--auto-scaling-role EMR_AutoScaling_DefaultRole \
--instance-groups \
InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m5.xlarge \
'InstanceGroupType=CORE,InstanceCount=2,InstanceType=m5.2xlarge,AutoScalingPolicy={
"Constraints":{"MinCapacity":2,"MaxCapacity":12},
"Rules":[
{
"Name":"ScaleOut",
"Description":"Ajout si mémoire YARN < 20%",
"Action":{"SimpleScalingPolicyConfiguration":{"AdjustmentType":"CHANGE_IN_CAPACITY","ScalingAdjustment":1,"CoolDown":300}},
"Trigger":{"CloudWatchAlarmDefinition":{
"ComparisonOperator":"LESS_THAN",
"EvaluationPeriods":1,
"MetricName":"YARNMemoryAvailablePercentage",
"Namespace":"AWS/ElasticMapReduce",
"Period":300,
"Threshold":20,
"Statistic":"AVERAGE",
"Unit":"PERCENT",
"Dimensions":[{"Key":"JobFlowId","Value":"${emr.clusterId}"}]
}}
}
]
}' \
--use-default-roles
Actions de démarrage (Bootstrap)
aws emr create-cluster \
--bootstrap-actions \
Path=s3://elasticmapreduce/bootstrap-actions/configure-hadoop,Name="Config-Hadoop",Args=[-m,mapred.map.tasks=80,-m,mapred.reduce.tasks=40] \
Path=s3://mon-bucket/scripts/installer-modules.sh,Name="Installer-Modules" \
--release-label emr-6.10.0 \
--instance-type m5.large \
--instance-count 3 \
--use-default-roles
Vue cohérente EMRFS
aws emr create-cluster \
--emrfs Consistent=true,RetryCount=5,RetryPeriod=30 \
--release-label emr-6.10.0 \
--instance-type m5.large \
--instance-count 3 \
--use-default-roles
Bonnes pratiques et optimisation
Privilégiez les instances Spot pour les groupes de tâches et utilisez une famille d’instances variée pour éviter les interruptions de capacité :
aws emr create-cluster \
--instance-fleets \
InstanceFleetType=MASTER,TargetOnDemandCapacity=1,InstanceTypeConfigs='[{InstanceType=m5.xlarge}]' \
InstanceFleetType=CORE,TargetSpotCapacity=10,InstanceTypeConfigs='[
{InstanceType=m5.2xlarge,BidPrice=0.4,WeightedCapacity=4},
{InstanceType=r5.2xlarge,BidPrice=0.5,WeightedCapacity=4},
{InstanceType=c5.2xlarge,BidPrice=0.35,WeightedCapacity=4}
]' \
--release-label emr-6.10.0 \
--service-role EMR_DefaultRole \
--ec2-attributes InstanceProfile=EMR_EC2_DefaultRole
Mettez en place des alarmes CloudWatch pour suivre l’utilisation mémoire :
aws cloudwatch put-metric-alarm \
--alarm-name "EMR-Memoire-Haute" \
--alarm-description "Alerte si mémoire EMR > 85%" \
--metric-name "MemoryUtilization" \
--namespace "AWS/ElasticMapReduce" \
--statistic "Average" \
--period 300 \
--threshold 85 \
--comparison-operator "GreaterThanThreshold" \
--evaluation-periods 2 \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:MonTopic" \
--dimensions Name=JobFlowId,Value=j-XXXXXXXXXX
Diagnostic des incidents
Identifier la cause d’un échec de création :
aws emr describe-cluster --cluster-id j-XXXXXXXXXX --query 'Cluster.Status.StateChangeReason'
Consulter les logs d’une étape défaillante :
aws emr ssh --cluster-id j-XXXXXXXXXX --key-pair-file ma-clef.pem --command "tail -100 /var/log/hadoop-yarn/containers/application_*/container_*/stdout"
Récupérer les métriques d’allocation de conteneurs :
aws cloudwatch get-metric-statistics \
--namespace AWS/ElasticMapReduce \
--metric-name ContainerAllocated \
--dimensions Name=JobFlowId,Value=j-XXXXXXXXXX \
--start-time 2024-06-01T00:00:00Z \
--end-time 2024-06-01T23:59:59Z \
--period 300 \
--statistics Average
Automatisation avec un script shell
#!/bin/bash
NOM_CLUSTER="Traitement-$(date +%Y%m%d-%H%M%S)"
VERSION_EMR="emr-6.10.0"
CHEMIN_LOGS="s3://mes-logs-emr/"
echo "Création du cluster $NOM_CLUSTER ..."
ID_CLUSTER=$(aws emr create-cluster \
--name "$NOM_CLUSTER" \
--release-label "$VERSION_EMR" \
--applications Name=Hadoop Name=Spark Name=Hive \
--instance-groups \
InstanceGroupType=MASTER,InstanceCount=1,InstanceType=m5.xlarge \
InstanceGroupType=CORE,InstanceCount=2,InstanceType=m5.2xlarge \
InstanceGroupType=TASK,InstanceCount=4,InstanceType=m5.2xlarge \
--use-default-roles \
--log-uri "$CHEMIN_LOGS" \
--auto-terminate \
--query 'ClusterId' \
--output text)
echo "Attente de disponibilité du cluster $ID_CLUSTER ..."
aws emr wait cluster-running --cluster-id "$ID_CLUSTER"
echo "Ajout de l'étape de traitement ..."
aws emr add-steps \
--cluster-id "$ID_CLUSTER" \
--steps Type=Spark,Name="MonJob",ActionOnFailure=CONTINUE,Args=[--class,com.exemple.MonJob,--master,yarn,--deploy-mode,cluster,s3://mon-bucket/jobs/monjob.jar,s3://entree/,s3://sortie/]
echo "Traitement lancé, le cluster s'arrêtera automatiquement."