

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.

# Trois types de tâches ETL AWS Glue pour convertir des données vers Apache Parquet
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet"></a>

*Adnan Alvee, Nith Govindasivan et Karthikeyan Ramachandran, Amazon Web Services*

## Résumé
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-summary"></a>

Sur le cloud Amazon Web Services (AWS), AWS Glue est un service d'extraction, de transformation et de chargement (ETL) entièrement géré. AWS Glue permet de classer vos données, de les nettoyer, de les enrichir et de les déplacer de manière fiable entre différents magasins de données et flux de données à moindre coût.

Ce modèle fournit différents types de tâches dans AWS Glue et utilise trois scripts différents pour illustrer la création de tâches ETL.

Vous pouvez utiliser AWS Glue pour écrire des tâches ETL dans un environnement shell Python. Vous pouvez également créer des tâches ETL par lots et en streaming en utilisant Python (PySpark) ou Scala dans un environnement Apache Spark géré. Pour vous aider à créer des tâches ETL, ce modèle se concentre sur les tâches ETL par lots à l'aide du shell Python et de Scala. PySpark Les jobs shell Python sont destinés aux charges de travail nécessitant une puissance de calcul moindre. L'environnement Apache Spark géré est destiné aux charges de travail nécessitant une puissance de calcul élevée.

Apache Parquet est conçu pour prendre en charge des schémas de compression et d'encodage efficaces. Il peut accélérer vos charges de travail d'analyse car il stocke les données sous forme de colonnes. La conversion de données au format Parquet peut vous faire économiser de l'espace de stockage, de l'argent et du temps à long terme. Pour en savoir plus sur Parquet, consultez le billet de blog [Apache Parquet : comment être un héros avec le format de données colonnaire open source](https://blog.openbridge.com/how-to-be-a-hero-with-powerful-parquet-google-and-amazon-f2ae0f35ee04).

## Conditions préalables et limitations
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-prereqs"></a>

**Conditions préalables**
+ Rôle AWS Identity and Access Management (IAM) (si vous n'avez pas de rôle, consultez la section [Informations supplémentaires](#three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-additional).)

## Architecture
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-architecture"></a>

**Pile technologique cible**
+ AWS Glue
+ Amazon Simple Storage Service (Amazon S3)
+ Apache Parquet

**Automatisation et mise à l'échelle**
+ [Les flux de travail AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/workflows_overview.html) prennent en charge l'automatisation complète d'un pipeline ETL.
+ Vous pouvez modifier le nombre d'unités de traitement des données (DPUs), ou les types de travailleurs, pour qu'ils soient redimensionnés horizontalement et verticalement.

## Outils
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-tools"></a>

**Services AWS**
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) est un service de stockage d'objets basé sur le cloud qui vous permet de stocker, de protéger et de récupérer n'importe quel volume de données.
+ [AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/what-is-glue.html) est un service ETL entièrement géré qui permet de classer, de nettoyer, d'enrichir et de déplacer vos données entre différents magasins de données et flux de données.

**Autres outils**
+ [Apache Parquet](https://parquet.apache.org/) est un format de fichier de données open source orienté colonne conçu pour le stockage et la récupération.

**Configuration**

Utilisez les paramètres suivants pour configurer la puissance de calcul d'AWS Glue ETL. Pour réduire les coûts, utilisez les paramètres minimaux lorsque vous exécutez la charge de travail fournie dans ce modèle. 
+ **Shell Python** — Vous pouvez utiliser 1 DPU pour utiliser 16 Go de mémoire ou 0,0625 DPU pour utiliser 1 Go de mémoire. Ce modèle utilise 0,0625 DPU, qui est la valeur par défaut dans la console AWS Glue.
+ **Python ou Scala pour Spark** : si vous choisissez les types de tâches liés à Spark dans la console, AWS Glue utilise par défaut 10 travailleurs et le type de travail G-1X. Ce modèle utilise deux travailleurs, qui est le nombre minimum autorisé, avec le type de travailleur standard, qui est suffisant et rentable.

Le tableau suivant présente les différents types de travailleurs AWS Glue pour l'environnement Apache Spark. Comme une tâche shell Python n'utilise pas l'environnement Apache Spark pour exécuter Python, elle n'est pas incluse dans le tableau.


| 
| 
|  | Standard | G.1X | G.2X | 
| --- |--- |--- |--- |
| vCPU | 4 | 4 | 8 | 
| Mémoire | 16 Go | 16 Go | 32 GO | 
| Espace disque | 50 Go | 64 Go | 128 Go | 
| Exécuteur par travailleur | 2 | 1  | 1 | 

**Code**

Pour le code utilisé dans ce modèle, y compris le rôle IAM et la configuration des paramètres, consultez la section [Informations supplémentaires](#three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-additional).

## Épopées
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-epics"></a>

### Téléchargez les données
<a name="upload-the-data"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| Téléchargez les données dans un compartiment S3 nouveau ou existant. | Créez ou utilisez un compartiment S3 existant dans votre compte. Téléchargez le fichier sample\$1data.csv depuis la section [Pièces jointes](#attachments-8c926709-8fa4-417f-9aaf-bcc8113d018f) et notez l'emplacement du compartiment S3 et du préfixe. | AWS général | 

### Création et exécution de la tâche AWS Glue
<a name="create-and-run-the-aws-glue-job"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| Créez la tâche AWS Glue. | Dans la section ETL de la console AWS Glue, ajoutez une tâche AWS Glue. Sélectionnez le type de tâche approprié, la version d'AWS Glue, ainsi que le DPU/Worker type et le nombre de travailleurs correspondants. Pour plus de détails, consultez la section *Configuration*. | Développeur, cloud ou données | 
| Modifiez les emplacements d'entrée et de sortie. | Copiez le code correspondant à votre tâche AWS Glue et modifiez l'emplacement d'entrée et de sortie indiqué dans l'épisode **Upload the data**. | Développeur, cloud ou données | 
| Configurez les paramètres. | Vous pouvez utiliser les extraits fournis dans la section [Informations supplémentaires](#three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-additional) pour définir les paramètres de votre tâche ETL. AWS Glue utilise quatre noms d'arguments en interne :[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/prescriptive-guidance/latest/patterns/three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet.html)Le `--JOB_NAME` paramètre doit être saisi explicitement sur la console AWS Glue. Choisissez **Tâches**, **Modifier la tâche**, **Configuration de sécurité, bibliothèques de scripts et paramètres de tâche (facultatif)**. Entrez `--JOB_NAME` comme clé et saisissez une valeur. Vous pouvez également utiliser l'interface de ligne de commande AWS (AWS CLI) ou l'API AWS Glue pour définir ce paramètre. Le `--JOB_NAME` paramètre est utilisé par Spark et n'est pas nécessaire dans une tâche d'environnement shell Python.Vous devez en ajouter `--` avant chaque nom de paramètre, sinon le code ne fonctionnera pas. Par exemple, pour les extraits de code, les paramètres de localisation doivent être invoqués par `--input_loc` et. `--output_loc` | Développeur, cloud ou données | 
| Exécutez le job ETL. | Exécutez votre tâche et vérifiez le résultat. Notez combien d'espace a été réduit par rapport au fichier d'origine. | Développeur, cloud ou données | 

## Ressources connexes
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-resources"></a>

**Références**
+ [Apache Spark](https://spark.apache.org/)
+ [AWS Glue : comment ça marche](https://docs.aws.amazon.com/glue/latest/dg/how-it-works.html)
+ [Tarification d'AWS Glue](https://aws.amazon.com/glue/pricing/)

**Tutoriels et vidéos**
+ [Qu'est-ce qu'AWS Glue ?](https://www.youtube.com/watch?v=qgWMfNSN9f4)

## Informations supplémentaires
<a name="three-aws-glue-etl-job-types-for-converting-data-to-apache-parquet-additional"></a>

**Rôle IAM**

Lorsque vous créez les tâches AWS Glue, vous pouvez utiliser soit un rôle IAM existant doté des autorisations indiquées dans l'extrait de code suivant, soit un nouveau rôle.

Pour créer un nouveau rôle, utilisez le code YAML suivant.

```
# (c) 2022 Amazon Web Services, Inc. or its affiliates. All Rights Reserved. This AWS Content is provided subject to the terms of the AWS Customer
# Agreement available at https://aws.amazon.com/agreement/ or other written agreement between Customer and Amazon Web Services, Inc.

AWSTemplateFormatVersion: "2010-09-09"

Description: This template will setup IAM role for AWS Glue service.

Resources:
  rGlueRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "glue.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole
      Policies:
        - PolicyName: !Sub "${AWS::StackName}-s3-limited-read-write-inline-policy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - "s3:PutObject"
                  - "s3:GetObject"
                Resource: "arn:aws:s3:::*/*"
      Tags:
        - Key  : "Name"
          Value : !Sub "${AWS::StackName}"

Outputs:
  oGlueRoleName:
    Description: AWS Glue IAM role
    Value:
      Ref: rGlueRole
    Export:
      Name: !Join [ ":", [ !Ref "AWS::StackName", rGlueRole ] ]
```

**Coque Python AWS Glue**

Le code Python utilise les Pandas et les PyArrow bibliothèques pour convertir les données en Parquet. La bibliothèque Pandas est déjà disponible. La PyArrow bibliothèque est téléchargée lorsque vous exécutez le modèle, car il s'agit d'une exécution unique. Vous pouvez utiliser des fichiers wheel pour les PyArrow convertir en bibliothèque et fournir le fichier sous forme de package de bibliothèque. Pour plus d'informations sur l'empaquetage des fichiers Wheel, consultez [Fournir votre propre bibliothèque Python](https://docs.aws.amazon.com/glue/latest/dg/add-job-python.html).

*Paramètres du shell AWS Glue Python*

```
from awsglue.utils import getResolvedOptions

args = getResolvedOptions(sys.argv, ["input_loc", "output_loc"])
```

*Code du shell AWS Glue Python*

```
from io import BytesIO
import pandas as pd
import boto3
import os
import io
import site
from importlib import reload
from setuptools.command import easy_install
install_path = os.environ['GLUE_INSTALLATION']
easy_install.main( ["--install-dir", install_path, "pyarrow"] )
reload(site)
import pyarrow


input_loc = "s3://bucket-name/prefix/sample_data.csv"
output_loc = "s3://bucket-name/prefix/"


input_bucket = input_loc.split('/', 1)[0]
object_key = input_loc.split('/', 1)[1]


output_loc_bucket = output_loc.split('/', 1)[0]
output_loc_prefix = output_loc.split('/', 1)[1] 


s3 = boto3.client('s3')
obj = s3.get_object(Bucket=input_bucket, Key=object_key)
df = pd.read_csv(io.BytesIO(obj['Body'].read()))


parquet_buffer = BytesIO()
s3_resource = boto3.resource('s3')
df.to_parquet(parquet_buffer, index=False) 
s3_resource.Object(output_loc_bucket, output_loc_prefix +  'data' + '.parquet').put(Body=parquet_buffer.getvalue())
```

**Tâche AWS Glue Spark avec Python**

Pour utiliser un type de tâche AWS Glue Spark avec Python, choisissez **Spark** comme type de tâche. Choisissez **Spark 3.1, Python 3 avec un temps de démarrage des tâches amélioré (Glue Version 3.0)** comme version AWS Glue.

*Paramètres Python d'AWS Glue*

```
from awsglue.utils import getResolvedOptions

args = getResolvedOptions(sys.argv, ["JOB_NAME", "input_loc", "output_loc"])
```

*Tâche AWS Glue Spark avec du code Python*

```
import sys
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.transforms import *
from awsglue.dynamicframe import DynamicFrame
from awsglue.utils import getResolvedOptions
from awsglue.job import Job


sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)

input_loc = "s3://bucket-name/prefix/sample_data.csv"
output_loc = "s3://bucket-name/prefix/"

inputDyf = glueContext.create_dynamic_frame_from_options(\
    connection_type = "s3", \
    connection_options = { 
        "paths": [input_loc]}, \
    format = "csv",
    format_options={
        "withHeader": True,
        "separator": ","
    })


outputDF = glueContext.write_dynamic_frame.from_options(\
    frame = inputDyf, \
    connection_type = "s3", \
    connection_options = {"path": output_loc \
        }, format = "parquet")
```

Pour un grand nombre de gros fichiers compressés (par exemple, 1 000 fichiers d'environ 3 Mo chacun), utilisez le `compressionType` paramètre associé au `recurse` paramètre pour lire tous les fichiers disponibles dans le préfixe, comme indiqué dans le code suivant.

```
input_loc = "bucket-name/prefix/"
output_loc = "bucket-name/prefix/"

inputDyf = glueContext.create_dynamic_frame_from_options(
                    connection_type = "s3", 
                    connection_options = {"paths": [input_loc], 
                                            "compressionType":"gzip","recurse" :"True",
                                            },
                    format = "csv",
                    format_options={"withHeader": True,"separator": ","}
                    )
```

Pour un grand nombre de petits fichiers compressés (par exemple, 1 000 fichiers d'environ 133 Ko chacun), utilisez le `groupFiles` paramètre ainsi que les `recurse` paramètres `compressionType` et. Le `groupFiles` paramètre regroupe les petits fichiers en plusieurs gros fichiers et contrôle le regroupement selon la taille spécifiée en octets (par exemple, 1 Mo). `groupSize` L'extrait de code suivant fournit un exemple d'utilisation de ces paramètres dans le code.

```
input_loc = "bucket-name/prefix/"
output_loc = "bucket-name/prefix/"

inputDyf = glueContext.create_dynamic_frame_from_options(
                    connection_type = "s3", 
                    connection_options = {"paths": [input_loc], 
                                            "compressionType":"gzip","recurse" :"True",
                                             "groupFiles" :"inPartition",  "groupSize" :"1048576",
                                            },
                    format = "csv",
                    format_options={"withHeader": True,"separator": ","}
                    )
```

Sans aucune modification des nœuds de travail, ces paramètres permettent à la tâche AWS Glue de lire plusieurs fichiers (grands ou petits, avec ou sans compression) et de les écrire sur la cible au format Parquet.

**Tâche AWS Glue Spark avec Scala**

Pour utiliser un type de tâche AWS Glue Spark avec Scala, choisissez **Spark** comme type de tâche et **Language** comme **Scala**. Choisissez **Spark 3.1, Scala 2 avec un temps de démarrage des tâches amélioré (Glue Version 3.0)** comme version AWS Glue. Pour économiser de l'espace de stockage, l'exemple d'AWS Glue with Scala suivant utilise également `applyMapping` cette fonctionnalité pour convertir les types de données.

*Paramètres d'AWS Glue Scala*

```
import com.amazonaws.services.glue.util.GlueArgParser val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME", "inputLoc", "outputLoc").toArray)
```

*Tâche AWS Glue Spark avec code Scala*

```
import com.amazonaws.services.glue.GlueContext
import com.amazonaws.services.glue.MappingSpec
import com.amazonaws.services.glue.DynamicFrame
import com.amazonaws.services.glue.errors.CallSite
import com.amazonaws.services.glue.util.GlueArgParser
import com.amazonaws.services.glue.util.Job
import com.amazonaws.services.glue.util.JsonOptions
import org.apache.spark.SparkContext
import scala.collection.JavaConverters._


object GlueScalaApp {
  def main(sysArgs: Array[String]) {
    
    @transient val spark: SparkContext = SparkContext.getOrCreate()
    val glueContext: GlueContext = new GlueContext(spark)

    val inputLoc = "s3://bucket-name/prefix/sample_data.csv"
    val outputLoc = "s3://bucket-name/prefix/"

    val readCSV = glueContext.getSource("csv", JsonOptions(Map("paths" -> Set(inputLoc)))).getDynamicFrame()

    val applyMapping = readCSV.applyMapping(mappings = Seq(("_c0", "string", "date", "string"), ("_c1", "string", "sales", "long"),
    ("_c2", "string", "profit", "double")), caseSensitive = false)

    val formatPartition = applyMapping.toDF().coalesce(1)

    val dynamicFrame = DynamicFrame(formatPartition, glueContext)

    val dataSink = glueContext.getSinkWithFormat(
        connectionType = "s3", 
        options = JsonOptions(Map("path" -> outputLoc )),
        transformationContext = "dataSink", format = "parquet").writeDynamicFrame(dynamicFrame)
  }
}
```

## Pièces jointes
<a name="attachments-8c926709-8fa4-417f-9aaf-bcc8113d018f"></a>

[Pour accéder au contenu supplémentaire associé à ce document, décompressez le fichier suivant : attachment.zip](samples/p-attach/8c926709-8fa4-417f-9aaf-bcc8113d018f/attachments/attachment.zip)