202 votes

Quels sont les avantages et les inconvénients du format parquet par rapport aux autres formats ?

Les caractéristiques d'Apache Parquet sont :

  • Autodéclaration
  • Format colonnaire
  • Indépendant de la langue

En comparaison avec Avro, Sequence Files, RC File etc. Je souhaite avoir une vue d'ensemble des formats. J'ai déjà lu : Comment Impala fonctionne avec les formats de fichiers Hadoop Il donne un aperçu des formats, mais j'aimerais savoir comment l'accès aux données et le stockage des données sont effectués dans chacun de ces formats. En quoi le parquet a-t-il un avantage sur les autres ?

4 votes

Un bon résumé peut être trouvé dans cette présentation : lien

0 votes

@ani-menon Le lien est mort.

0 votes

@SajjadHossain mis à jour.

377voto

Tom Harrison Jr Points 5855

Je pense que la principale différence que je peux décrire concerne les formats orientés enregistrements et les formats orientés colonnes. Les formats orientés enregistrement sont ceux auxquels nous sommes tous habitués - fichiers texte, formats délimités comme CSV, TSV. AVRO est un peu plus cool que ces derniers car il peut changer de schéma au fil du temps, par exemple en ajoutant ou en supprimant des colonnes d'un enregistrement. D'autres astuces pour les différents formats (notamment la compression) consistent à savoir si un format peut être divisé - c'est-à-dire si vous pouvez lire un bloc d'enregistrements à partir de n'importe quel endroit de l'ensemble de données tout en connaissant son schéma. Voici plus de détails sur les formats colonnaires comme Parquet.

Parquet et d'autres formats en colonnes gèrent très efficacement une situation courante dans Hadoop. Il est courant d'avoir des tables (ensembles de données) comportant beaucoup plus de colonnes que ce que l'on attendrait d'une base de données relationnelle bien conçue - une centaine ou deux cents colonnes ne sont pas inhabituelles. Il en est ainsi parce que nous utilisons souvent Hadoop comme un endroit pour dénormaliser les données provenant de formats relationnels - oui, vous obtenez beaucoup de valeurs répétées et de nombreuses tables, toutes aplaties en une seule. Mais il est beaucoup plus facile d'effectuer des requêtes puisque toutes les jointures sont effectuées. Il y a d'autres avantages, comme la conservation des données en temps réel. De toute façon, il est courant d'avoir un grand nombre de colonnes dans une table.

Disons qu'il y a 132 colonnes, et que certaines d'entre elles sont des champs de texte très longs, chaque colonne différente se suivant l'une l'autre et utilisant peut-être 10K par enregistrement.

Bien que l'interrogation de ces tables soit facile avec le point de vue de SQL, il est fréquent que vous souhaitiez obtenir une série d'enregistrements en vous basant sur quelques-unes seulement de ces plus de cent colonnes. Par exemple, vous pouvez vouloir tous les enregistrements des mois de février et mars pour les clients dont les ventes sont supérieures à 500 $.

Pour effectuer cette opération au format ligne, la requête doit analyser chaque enregistrement de l'ensemble de données. Lire la première ligne, analyser l'enregistrement en champs (colonnes) et obtenir les colonnes de date et de ventes, l'inclure dans votre résultat s'il satisfait à la condition. Répétez l'opération. Si vous avez 10 ans (120 mois) d'historique, vous lisez chaque enregistrement juste pour trouver 2 de ces mois. Bien sûr, c'est une excellente occasion d'utiliser une partition sur l'année et le mois, mais même ainsi, vous lisez et analysez 10K de chaque enregistrement/rangée pour ces deux mois, juste pour savoir si les ventes du client sont > 500 $.

Dans un format en colonnes, chaque colonne (champ) d'un enregistrement est stockée avec d'autres de son type, réparties sur de nombreux blocs différents sur le disque - les colonnes pour l'année ensemble, les colonnes pour le mois ensemble, les colonnes pour le manuel du client et de l'employé (ou tout autre texte long), et toutes les autres qui rendent ces enregistrements si énormes, toutes dans leur propre endroit séparé sur le disque, et bien sûr les colonnes pour les ventes ensemble. Mais bon, la date et les mois sont des nombres, tout comme les ventes - ils ne représentent que quelques octets. Ne serait-il pas formidable de n'avoir à lire que quelques octets pour chaque enregistrement afin de déterminer ceux qui correspondent à notre requête ? Le stockage colonnaire à la rescousse !

Même sans partitions, le balayage des petits champs nécessaires pour satisfaire notre requête est super rapide. Ils sont tous classés par enregistrement et ont tous la même taille, de sorte que le disque recherche beaucoup moins de données pour vérifier les enregistrements inclus. Il n'est pas nécessaire de lire le manuel de l'employé et les autres longs champs de texte - il suffit de les ignorer. Ainsi, en regroupant les colonnes entre elles, plutôt que les lignes, vous pouvez presque toujours analyser moins de données. Gagnant !

Mais attendez, il y a mieux. Si votre requête n'avait besoin de connaître que ces valeurs et quelques autres (disons 10 des 132 colonnes) et ne se souciait pas de la colonne "manuel de l'employé", une fois qu'elle aurait choisi les bons enregistrements à renvoyer, elle n'aurait plus qu'à revenir aux 10 colonnes dont elle avait besoin pour rendre les résultats, en ignorant les 122 autres colonnes sur les 132 de notre ensemble de données. Encore une fois, nous sautons beaucoup de lecture.

(Note : pour cette raison, les formats en colonnes sont un mauvais choix pour les transformations directes, par exemple, si vous joignez deux tables en un seul grand ensemble de résultats que vous sauvegardez comme une nouvelle table, les sources vont être scannées complètement de toute façon, donc il n'y a pas beaucoup d'avantages en termes de performances de lecture, et parce que les formats en colonnes doivent se souvenir de l'emplacement des éléments, ils utilisent plus de mémoire qu'un format en lignes similaire).

Un autre avantage du columnar : les données sont réparties dans tous les sens. Pour obtenir un seul enregistrement, vous pouvez demander à 132 travailleurs de lire (et d'écrire) des données depuis/vers 132 endroits différents sur 132 blocs de données. Bravo pour la parallélisation !

Et maintenant, l'argument décisif : les algorithmes de compression fonctionnent beaucoup mieux lorsqu'ils peuvent trouver des motifs répétitifs. Vous pourriez compresser AABBBBBBCCCCCCCCCCCCCCCC como 2A6B16C mais ABCABCBCBCBCCCCCCCCCCCCCC ne serait pas aussi petit (en fait, dans ce cas, si, mais croyez-moi :-) ). Donc, une fois de plus, moins de lecture. Et d'écriture aussi.

Nous lisons donc beaucoup moins de données pour répondre aux requêtes courantes, il est potentiellement plus rapide de lire et d'écrire en parallèle, et la compression a tendance à fonctionner beaucoup mieux.

La méthode colonnaire est idéale lorsque le côté d'entrée est important et que la sortie est un sous-ensemble filtré : du grand au petit, c'est génial. Il n'est pas aussi avantageux lorsque l'entrée et la sortie sont à peu près identiques.

Mais dans notre cas, Impala a pris nos anciennes requêtes Hive qui s'exécutaient en 5, 10, 20 ou 30 minutes, et a terminé la plupart en quelques secondes ou une minute.

J'espère que cela répondra au moins en partie à votre question !

7 votes

Excellent. Merci. C'est un résumé très utile qui manque dans de nombreuses documentations sur les projets Apache. Vous mentionnez : "les petits champs ... sont tous dans l'ordre par enregistrement". Supposons que j'ai une table simple de userid:long et age:int, et que je veux trouver tous les utilisateurs entre un certain âge. Ici, j'ai deux colonnes. Dois-je préciser quand est l'index pour l'ordre, ou est-ce que TOUTES les colonnes sont efficacement indexables ?

1 votes

Que faire si j'utilise le parquet pour une série temporelle ? Plusieurs colonnes (100+), chaque colonne est une donnée de capteur avec une fréquence différente (100hz à 0.25 hz). Serait-ce une bonne décision ?

76voto

afuc func Points 412

Avro est un format de stockage par rangée pour Hadoop.

Parquet est un format de stockage en colonnes pour Hadoop.

Si votre cas d'utilisation consiste généralement à balayer ou à récupérer tous les champs d'une ligne dans chaque requête, Avro est généralement le meilleur choix.

Si votre jeu de données comporte de nombreuses colonnes, et que votre cas d'utilisation implique généralement de travailler avec un sous-ensemble de ces colonnes plutôt qu'avec des enregistrements entiers, Parquet est optimisé pour ce type de travail.

Source :

32voto

Justin Kestelyn Points 666

La réponse de Tom est assez détaillée et exhaustive, mais vous pouvez également être intéressé par les éléments suivants cette simple étude sur Parquet vs Avro fait chez Allstate Insurance, résumé ici :

"Dans l'ensemble, Parquet a obtenu des résultats similaires ou supérieurs à ceux d'Avro pour chaque test. Les différences de performance de requête sur les grands ensembles de données en faveur de Parquet sont en partie dues aux résultats de la compression ; lors de l'interrogation du grand ensemble de données, Spark a dû lire 3,5 fois moins de données pour Parquet qu'Avro. Avro n'a pas obtenu de bonnes performances lors du traitement de l'ensemble des données, comme on s'y attendait."

24voto

Powers Points 1742

Le choix du bon format de fichier est important pour créer des applications de données performantes. Les concepts décrits dans cet article s'appliquent à Pandas, Dask, Spark et Presto / AWS Athena.

Élagage des colonnes

L'élagage des colonnes est une amélioration importante des performances qui est possible pour les formats de fichiers basés sur des colonnes (Parquet, ORC) et impossible pour les formats de fichiers basés sur des lignes (CSV, Avro).

Supposons que vous disposiez d'un ensemble de données comportant 100 colonnes et que vous souhaitiez lire deux d'entre elles dans un DataFrame. Voici comment vous pouvez effectuer cette opération avec Pandas si les données sont stockées dans un fichier Parquet.

import pandas as pd

pd.read_parquet('some_file.parquet', columns = ['id', 'firstname'])

Parquet étant un format de fichier en colonnes, Pandas peut saisir les colonnes pertinentes pour la requête et ignorer les autres colonnes. Il s'agit d'une amélioration considérable des performances.

Si les données sont stockées dans un fichier CSV, vous pouvez le lire comme suit :

import pandas as pd

pd.read_csv('some_file.csv', usecols = ['id', 'firstname'])

usecols ne peut pas sauter des colonnes entières en raison de la nature des lignes du format de fichier CSV.

Spark ne demande pas aux utilisateurs de lister explicitement les colonnes qui seront utilisées dans une requête. Spark construit un plan d'exécution et exploitera automatiquement l'élagage des colonnes chaque fois que possible. Bien sûr, l'élagage des colonnes n'est possible que lorsque le format de fichier sous-jacent est orienté colonnes.

Popularité

Spark et Pandas ont des lecteurs-graveurs intégrés pour les fichiers CSV, JSON, ORC, Parquet et texte. Ils n'ont pas de lecteurs intégrés pour Avro.

Avro est populaire dans l'écosystème Hadoop. Parquet a gagné en popularité en dehors de l'écosystème Hadoop. Par exemple, le Lac Delta Le projet est construit sur des fichiers Parquet.

Flèche est un projet important qui permet de travailler facilement avec des fichiers Parquet avec une variété de langages différents (C, C++, Go, Java, JavaScript, MATLAB, Python, R, Ruby, Rust), mais ne supporte pas Avro. Il est plus facile de travailler avec les fichiers Parquet parce qu'ils sont supportés par un grand nombre de projets différents.

Schéma

Parquet stocke le schéma du fichier dans les métadonnées du fichier. Les fichiers CSV ne stockent pas de métadonnées de fichier, donc les lecteurs doivent soit recevoir le schéma, soit le déduire. Fournir un schéma est fastidieux et déduire un schéma est source d'erreurs et coûteux.

Avro stocke également le schéma de données dans le fichier lui-même. Le fait d'avoir le schéma dans les fichiers est un avantage énorme et c'est l'une des raisons pour lesquelles un projet de données moderne ne devrait pas s'appuyer sur JSON ou CSV.

Métadonnées des colonnes

Magasins de parquet statistiques des métadonnées pour chaque colonne y permet aux utilisateurs d'ajouter leurs propres métadonnées de colonne également.

Les métadonnées des valeurs min. et max. des colonnes permettent le filtrage par prédicat Parquet pushdown, qui est pris en charge par les cadres de calcul en cluster Dask et Spark.

Voici comment récupérer les statistiques des colonnes avec PyArrow.

import pyarrow.parquet as pq

parquet_file = pq.ParquetFile('some_file.parquet')
print(parquet_file.metadata.row_group(0).column(1).statistics)

<pyarrow._parquet.Statistics object at 0x11ac17eb0>
  has_min_max: True
  min: 1
  max: 9
  null_count: 0
  distinct_count: 0
  num_values: 3
  physical_type: INT64
  logical_type: None
  converted_type (legacy): NONE

Types de colonnes complexes

Parquet permet des types de colonnes complexes comme les tableaux, les dictionnaires et les schémas imbriqués. Il n'existe pas de méthode fiable pour stocker des types complexes dans des formats de fichiers simples comme les CSV.

Compression

Les formats de fichiers en colonnes stockent les types apparentés en rangées, ce qui les rend plus faciles à compresser. Ce fichier CSV est relativement difficile à compresser.

first_name,age
ken,30
felicia,36
mia,2

Ces données sont plus faciles à compresser lorsque les types apparentés sont stockés dans la même ligne :

ken,felicia,mia
30,36,2

Les fichiers Parquet sont le plus souvent compressés avec l'algorithme de compression Snappy. Les fichiers compressés par Snappy sont fractionnables et rapides à gonfler. Les systèmes de big data veulent réduire la taille des fichiers sur le disque, mais veulent aussi qu'il soit rapide de gonfler les mouches et d'exécuter des requêtes analytiques.

Caractère mutable du dossier

Les fichiers Parquet sont immuables, comme décrit ici . CSV sont mutables.

Ajouter une ligne à un fichier CSV est facile. Vous ne pouvez pas facilement ajouter une ligne à un fichier Parquet.

Lacs de données

Dans un environnement de big data, vous travaillerez avec des centaines ou des milliers de fichiers Parquet. Il est important de partitionner les fichiers sur le disque, d'éviter les gros fichiers et de compacter les petits fichiers. La disposition optimale des données sur le disque dépend de vos modèles de requête.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X