Vous avez un pipeline qui exporte chaque nuit une table de transactions vers un fichier CSV posé sur un stockage objet. Le lendemain, l’équipe analytique le relit entièrement pour calculer trois agrégats sur trois colonnes, alors que le fichier en compte quarante. Elle paie la lecture des trente-sept autres, le reparsing de chaque champ texte et la redécouverte des types à chaque exécution.
Le vrai goulot d’étranglement est ici le format de fichier, pas le pipeline. Apache Hop sait écrire et relire du Parquet, un format colonne compressé qui embarque son propre schéma. Cet article montre comment le mettre en place, et quelles options surveiller pour éviter les deux ennuis classiques : les fichiers démesurés et les erreurs de typage au retour.
Prérequis
- Apache Hop installé. La version stable courante au moment de la rédaction est la 2.19.0, publiée le 17 août 2026, distribuée sous la forme de l’archive
apache-hop-client-2.19.0.zip. - Java 21, exigé par cette version de Hop.
- Un projet Hop configuré avec au moins une configuration d’exécution.
- Un pipeline existant produisant des lignes typées, par exemple une lecture de base de données.
1. Ce que change réellement un format colonne
Un CSV stocke les données ligne par ligne : pour atteindre la troisième colonne de la millionième ligne, il faut avoir traversé tout ce qui précède. Parquet inverse cette organisation en regroupant physiquement les valeurs d’une même colonne.
| Aspect | CSV | Parquet |
|---|---|---|
| Organisation | Par ligne | Par colonne, en groupes de lignes |
| Lecture partielle | Tout le fichier | Seules les colonnes demandées |
| Schéma | Absent, à redéclarer | Embarqué dans le fichier |
| Compression | Globale, sur du texte | Par colonne, sur des valeurs homogènes |
| Typage | Tout est chaîne de caractères | Types natifs conservés |
Le gain de compression vient de l’homogénéité : une colonne de codes pays ne contient qu’une poignée de valeurs distinctes, et se compresse bien mieux isolée que mélangée à des montants et des horodatages. Le schéma embarqué, lui, supprime une source d’erreur récurrente : c’est le fichier qui déclare le type de chaque champ, et non une convention que l’on espère respectée de part et d’autre.
2. Écrire un premier fichier Parquet
Ajoutez un transform Parquet file output en sortie de votre pipeline. La documentation le résume ainsi : il écrit les données au format Apache Parquet.
Deux options construisent le nom du fichier.
- Base file name : le chemin et le début du nom. La documentation donne deux exemples,
s3://my-bucket-name/transactionspour un bucket Amazon S3 et/my/folder/customer-datapour un dossier local. - Extension : l’extension du fichier, pour laquelle la documentation indique la valeur
snappycomme usage courant.
Viennent ensuite les options d’horodatage et de découpage, chacune avec son masque documenté :
| Option | Effet |
|---|---|
| Include date? | Insère la date dans le nom du fichier |
| Include time? | Insère l’heure, au masque HHmmss |
| Include date-time-format? | Insère un format date-heure personnalisé |
| Include transform copy number? | Insère le numéro de copie, au masque 00 |
| Split into parts and include number? | Insère le numéro de partie, au masque 0000 |
Attention sur un point : la date éventuellement présente dans le nom du fichier est celle du début de l’exécution du pipeline, non celle du moment où la ligne est écrite. Pour un pipeline nocturne démarré à 23 h 58 et terminé après minuit, c’est la date de la veille qui sera retenue. Si votre convention de nommage doit refléter la date de traitement métier, passez-la en paramètre et utilisez une variable dans le Base file name.
Enfin, dès que vous faites tourner ce transform en plusieurs copies pour exploiter le parallélisme, activez Include transform copy number? : sans cela, plusieurs threads écrivent dans le même fichier.
3. Maîtriser la mémoire et la taille des fichiers
C’est le piège principal, et la documentation est explicite : la compression vers le format colonne se fait en mémoire, au moment où toutes les lignes ont été écrites. Un pipeline qui pousse cinquante millions de lignes vers un unique fichier accumule donc l’ensemble en mémoire avant d’écrire. La recommandation officielle est sans ambiguïté : pour ne pas épuiser la mémoire, précisez une taille de découpage. Activez donc Split into parts and include number? avec une taille supérieure à zéro, qui correspond au nombre de lignes par fichier ; le numéro de partie est ajouté au nom pour qu’un fichier n’en écrase pas un autre.
Trois autres paramètres règlent la structure interne du fichier :
| Option | Signification | Valeur par défaut |
|---|---|---|
| Compression codec | Codec de compression utilisé | SNAPPY |
| Version | Version du protocole Parquet (1.0 ou 2.0) | — |
| Row group size | Nombre de lignes dans un groupe | — |
| Data page size | Taille de page de données, sur une frontière de 1 ko | 1048576 |
| Dictionary page size | Taille de page du dictionnaire, sur une frontière de 1 ko | 1048576 |
Une dernière option concerne l’interopérabilité : Include compression codec before extension?, activée par défaut pour les nouveaux transforms, place le codec avant l’extension — file.snappy.parquet — ce qui correspond au nommage employé par Spark et les autres outils Parquet. Désactivée, le codec est ajouté après l’extension, soit file.parquet.snappy ; les pipelines existants qui n’ont pas cette option conservent ce comportement antérieur. Si un consommateur externe ne reconnaît pas vos fichiers, vérifiez ce réglage avant tout.
4. Relire les fichiers produits
Le transform de lecture s’appelle Parquet File Input. Sa documentation précise qu’il lit les valeurs (primitives) depuis un fichier Apache Parquet.
Première différence avec les transforms de lecture habituels : il n’y a pas de nom de fichier à saisir en dur. L’option Filename field attend un champ d’entrée contenant le chemin ; la documentation renvoie vers un transform comme Get File Names pour obtenir ces noms et précise que tout emplacement de fichier supporté convient. Le montage est donc : un transform qui liste les fichiers, puis Parquet File Input qui les consomme.
Deuxième option précieuse, Metadata filename : en indiquant un fichier à cet endroit, vous pouvez laisser la grille des champs vide et Hop déterminera automatiquement les champs de sortie. Cela évite de redéclarer manuellement des métadonnées déjà présentes dans le schéma du fichier Parquet. Le bouton Get fields remplit la grille à partir d’un fichier de votre choix.
L’option Output null row when empty couvre un cas limite utile : si aucune ligne n’est trouvée, vous recevez une ligne vide, exploitable pour extraire des métadonnées avec le transform Metadata structure of stream.
Côté ressources : pour permettre la lecture depuis n’importe quel emplacement via Apache VFS, chaque fichier est chargé en mémoire, un à la fois. Prévoyez la mémoire en conséquence — une raison supplémentaire de découper vos fichiers à l’écriture.
5. Les pièges de typage
Parquet conserve les types, mais la correspondance avec les types Hop n’est pas tout à fait transparente. Les comportements documentés à connaître :
- Dates à l’écriture : les types Date de Hop sont sérialisés en EPOCH, c’est-à-dire en millisecondes depuis
1970-01-01 00:00:00.000. - Dates à la lecture : symétriquement, les valeurs Long peuvent être désérialisées en Dates si elles sont des EPOCH en millisecondes. Vous devez donc déclarer vous-même le type Date voulu dans la grille des champs ; une colonne de dates relue sans précaution revient en numérique.
- Chaînes de caractères : à l’écriture, elles sont écrites en binaire UTF-8. À la lecture, les champs Binary de Parquet sont considérés comme des String Hop, mais vous pouvez les lire en Binary si besoin.
- INT96 : converti vers le type Binary de Hop. C’est un type ancien, utilisé par certains producteurs pour les horodatages ; prévoyez une conversion explicite en aval.
- En lecture, toutes les valeurs d’entrée sont passées en sortie.
Le réflexe à prendre : après la mise en place d’un aller-retour écriture puis lecture, comparez les types annoncés dans la grille des champs avec ceux du pipeline d’origine, avant de brancher quoi que ce soit en aval.
6. Parquet et les moteurs d’exécution
Les deux transforms sont déclarés compatibles avec plusieurs moteurs, ce qui en fait de bons candidats pour les traitements distribués abordés dans l’article consacré à Apache Beam.
| Transform | Moteurs documentés comme supportés |
|---|---|
| Parquet File Input | Hop Engine, Spark, Flink, Dataflow |
| Parquet file output | Hop Engine, Single Threaded, Native Spark, Beam Spark, Beam Flink, Beam Dataflow |
Hop fournit également des transforms Avro file input, Avro file output, Avro decode et Avro encode : Avro est un format orienté ligne, adapté au transport de messages, là où Parquet vise l’analytique. En revanche, la liste standard des transforms ne comporte pas de transform ORC ; si votre cible impose ce format, il faudra passer par un traitement externe.
7. Exécuter le pipeline en ligne de commande
Une fois le pipeline au point dans Hop GUI, l’exécution planifiée passe par hop-run.sh sur Mac et Linux, ou hop-run.bat sur Windows :
./hop-run.sh \
--project=ventes \
--runconfig=local \
--file=${PROJECT_HOME}/pipelines/export-parquet.hpl \
--parameters=DATE_EXPORT=2026-11-02,CHEMIN_CIBLE=s3://mon-bucket/transactions \
--level=BASIC
Les formes courtes sont -j, -r, -f, -p et -l, ce dernier acceptant l’une des valeurs NOTHING, ERROR, MINIMAL, BASIC, DETAILED, DEBUG, ROWLEVEL. Si une valeur de paramètre contient une virgule, -ps permet de changer le séparateur de la liste.
Côté supervision, les codes de retour documentés permettent de piloter l’ordonnanceur : 0 si tout s’est bien passé, 1 en cas d’erreur pendant l’exécution, 2 pour une erreur générale ayant fait échouer complètement Hop Run, 9 pour une erreur d’analyse des paramètres.
Conclusion
Vous savez désormais produire des fichiers Parquet depuis Hop sans saturer la mémoire du serveur, les relire en vous appuyant sur le schéma embarqué plutôt que sur une déclaration manuelle de quarante champs, et anticiper les trois conversions de types qui causent le plus de surprises : dates en EPOCH, chaînes en binaire UTF-8 et INT96. Vous disposez en outre de deux réflexes de diagnostic : la taille de découpage devant un problème de mémoire, l’option de placement du codec devant un problème d’interopérabilité.
L’étape suivante consiste à faire tourner ce même pipeline sur un moteur distribué : les deux transforms y sont supportés, et le passage à l’échelle ne demande qu’un changement de configuration d’exécution.
Pour aller plus loin
- Documentation du transform Parquet File Input
- Documentation du transform Parquet file output
- Liste complète des transforms Apache Hop
- Documentation de Hop Run et de ses options en ligne de commande
- Configurations d’exécution de pipeline
- Site officiel du projet Apache Parquet
- Page de téléchargement d’Apache Hop