Partitions et compartiments Hive avec exemple

⚡ Résumé intelligent

Apache Hive utilise deux méthodes pour répartir les données d'une table sur disque : une partition crée un répertoire par valeur de clé, tandis qu'un bucket répartit les lignes dans un nombre fixe de fichiers.

  • 🇧🇷 Une partition est un répertoire : Chaque valeur distincte de la clé de partition devient son propre sous-répertoire sous le dossier de la table dans HDFS.
  • ✂️ Élagage par partition : Une requête qui filtre sur la clé de partition ne lit que les répertoires correspondants au lieu d'analyser la table entière.
  • ⚙️ Mode dynamique requis : Le chargement de nombreuses partitions à partir d'une requête SELECT nécessite que hive.exec.dynamic.partition.mode soit défini sur nonstrict.
  • 🧮 Bucket est un fichier : CLUSTERED BY hache la colonne choisie et écrit chaque ligne dans l'un des fichiers d'un nombre fixe.
  • 🔍 Échantillonnage et jonctions : Les tables compartimentées prennent en charge des lectures TABLESAMPLE efficaces et des jointures de compartiments côté map que les tables simples ne peuvent pas.
  • (I.e. Choisir par cardinalité : Partitionnez les données selon les colonnes à faible cardinalité telles que l'état ou la date, et regroupez celles selon les colonnes à forte cardinalité telles que les identifiants utilisateur.

Explication des partitions et des buckets Hive avec un exemple concret

Les tables, les partitions et les buckets constituent les éléments de la modélisation des données Hive. Une table définit le schéma, une partition divise cette table en répertoires sur le disque, et un bucket répartit les données d'un répertoire en un nombre fixe de fichiers.

Qu’est-ce que les partitions ?

Les partitions Hive permettent d'organiser les tables en les divisant en différentes parties selon des clés de partition. Physiquement, chaque partition correspond à un sous-répertoire distinct du dossier de la table dans HDFS, ce qui permet à Hive d'ignorer les données inutiles.

Le partitionnement est utile lorsqu'une table comporte une ou plusieurs clés de partitionnement. Ces clés sont essentielles pour déterminer la manière dont les données sont stockées dans la table. Une clé de partitionnement n'est pas stockée dans les fichiers de données eux-mêmes ; sa valeur est encodée dans le nom du répertoire. Ainsi, une requête filtrant sur cette clé peut exclure des répertoires entiers avant même la lecture d'une ligne. C'est ce qu'on appelle l'élagage de partitions.

Par exemple: -

« Notre client possède des données de commerce électronique relatives à ses opérations en Inde, où les opérations de chaque État (38 États) sont regroupées. En utilisant la colonne « État » comme clé de partitionnement et en partitionnant ces données, nous obtenons 38 partitions, soit autant que d’États en Inde. Ainsi, les données de chaque État peuvent être visualisées séparément dans les tables de partitionnement. »

Échantillon Code Extrait pour les partitions

Les six instructions ci-dessous s'exécutent séquentiellement dans l'interface Hive. Chacune correspond à une étape distincte, et les captures d'écran suivantes illustrent l'exécution de cette même séquence sur un cluster en production.

  1. Création de la table allstates
    create table allstates(state string, District string,Enrolments string)
    
    row format delimited
    
    fields terminated by ',';
    
  2. Chargement des données dans la table créée allstates
    Load data local inpath '/home/hduser/Desktop/AllStates.csv' into table allstates;
  3. Création d'une table de partition
    create table state_part(District string,Enrolments string) PARTITIONED BY(state string);
  4. Pour la partition, nous devons définir cette propriété
    set hive.exec.dynamic.partition.mode=nonstrict
  5. Chargement des données dans la table de partition
    INSERT OVERWRITE TABLE state_part PARTITION(state)
    SELECT district,enrolments,state from  allstates;
  6. Traitement réel et formation des tables de partition basées sur l'état comme clé de partition

Il y aura 38 partitions de sortie dans le système de stockage HDFS, chacune portant le nom de son état. Nous vérifierons cela dans cette étape.

Les captures d'écran suivantes illustrent l'exécution du code mentionné ci-dessus.

Sur le premier écran, l'étape 1 s'exécute à la ruche> invite et crée l'invite et crée le Allstates tableau à trois colonnes avec une virgule comme délimiteur de champ.

Interface Hive créant la table allstates avec trois colonnes délimitées

L'écran suivant illustre les étapes 2 et 3 : le fichier AllStates.csv est chargé dans Allstates, et la table partitionnée partie_état est créé avec l'état déclaré comme clé de partition.

Chargement du fichier AllStates.csv dans allstates et création de la table partitionnée state_part

Les étapes 4 et 5 apparaissent ensuite. Le mode de partitionnement dynamique est défini sur non strict, et l'instruction INSERT OVERWRITE lance une tâche MapReduce dont les lignes de journal indiquent qu'une partition est chargée pour chaque valeur d'état.

Chargement de la sortie d'une tâche MapReduce, une partition Hive par valeur d'état

L'affichage du répertoire de l'entrepôt dans HDFS confirme le résultat de l'étape 6 : le shell signale 38 éléments, dont un partie_état/état= Répertoire par état.

Liste HDFS affichant 38 répertoires de partition state_part dans l'entrepôt de données Hive

À partir du code ci-dessus, nous faisons les choses suivantes

  1. Création de la table allstates avec 3 noms de colonnes : state, district et enrolments
  2. Chargement des données dans la table allstates
  3. Création d'une table de partition avec l'état comme clé de partition
  4. Dans cette étape, définissez le mode de partitionnement sur non strict (ce mode activera le mode de partitionnement dynamique).
  5. Chargement des données dans la table de partition state_part
  6. Traitement réel et formation des tables de partition basées sur l'état comme clé de partition
  7. Il y aura 38 partitions de sortie dans le système de stockage HDFS, chacune portant le nom d'état du fichier. Dans cette étape, nous visualisons ces 38 partitions de sortie dans HDFS.

Partitionnement statique vs dynamique dans Hive

L'exemple ci-dessus utilise le partitionnement dynamique, mais Hive prend en charge deux styles de chargement ; la différence détermine la quantité de données à charger.ping – et quel niveau de risque – chaque chargement comporte.

Partitionnement statique La valeur de la partition est indiquée dans l'instruction elle-même ; par conséquent, cette valeur doit être connue avant l'exécution du chargement et une instruction remplit exactement une seule partition. Partitionnement dynamique permet à Hive de lire la valeur de partition dans la dernière colonne de la liste SELECT et de créer les répertoires au moment de l'exécution, c'est pourquoi l'exemple ne nécessite qu'une seule instruction INSERT pour produire 38 répertoires.

Aspect Partitionnement statique Partitionnement dynamique
Valeur de partition Fourni en main propre dans la clause de PARTITION Lire à l'exécution à partir de la colonne SELECT
Partitions par relevé Un Merci beaucoup
Configuration Fonctionne en mode strict par défaut Nécessite que hive.exec.dynamic.partition.mode soit défini sur nonstrict
Vitesse de chargement Plus rapide, car aucune analyse de valeur n'est nécessaire Plus lent, car le traitement regroupe les lignes par clé
Meilleur adapté à De petits ensembles connus, comme une charge quotidienne Des ensembles de clés importants ou inconnus, tels que 38 états

Les charges dynamiques sont également plafonnées. Hive limite le nombre de partitions qu'une tâche peut créer (par défaut 100 par mapper ou reducer et 1000 pour l'ensemble de l'instruction). La tâche échoue dès que l'une de ces limites est atteinte ; par conséquent, une clé à cardinalité très élevée nécessite d'augmenter ces limites ou d'adopter une conception différente.

Qu'est-ce que les godets ?

Dans Hive, les buckets servent à répartir les données d'une table dans plusieurs fichiers ou répertoires. Ils permettent d'effectuer des requêtes efficaces et, contrairement aux partitions, leur nombre est fixe lors de la création de la table ; il ne s'accroît donc jamais avec la taille des données.

  • Les données présentes dans ces partitions peuvent être divisées en compartiments supplémentaires.
  • La division est effectuée en fonction du hachage de colonnes spécifiques que nous avons sélectionnées dans le tableau.
  • Les compartiments utilisent une forme d'algorithme de hachage en arrière-plan pour lire chaque enregistrement et le placer dans un compartiment.
  • Le compartiment dans lequel atterrit une rangée est déterminé par fonction_de_hachage(colonne_de_bucketing) mod num_buckets, donc les valeurs égales se retrouvent toujours dans le même fichier
  • Sur Hive 0.x et 1.x, le compartimentage devait être activé avec définir hive.enforce.bucketing=true ; avant l'insertion

Ce dernier paramètre correspond à l'historique du cluster actuel : le manuel Apache Hive Il est à noter que cela n'est plus nécessaire à partir de Hive 2.x, car le moteur sélectionne désormais automatiquement le nombre de réducteurs et la colonne de regroupement à partir de la définition de la table.

Étape 1) Création d'un bucket comme indiqué ci-dessous.

La capture d'écran ci-dessous affiche l'instruction CREATE TABLE pour échantillonneur, la clause CLUSTERED BY en bas fixant le nombre de compartiments.

Instruction CREATE TABLE Hive regroupant samplebucket en quatre compartiments

D'après la capture d'écran ci-dessus

  • Nous créons un échantillon de données avec des colonnes nommées comme prénom, identifiant_de_poste, département, salaire et pays.
  • Nous sommes en train de créer 4 seaux ici.
  • Une fois les données chargées, elles sont automatiquement réparties dans 4 compartiments.
  • La colonne « pays » sert de colonne de regroupement ; ainsi, chaque ligne correspondant à un même pays est écrite dans le même fichier bucket.

Étape 2) Chargement des données dans la table samplebucket

En supposant que la table « employees » soit déjà créée dans le système Hive, cette étape verra le chargement des données de la table « employees » dans la table « samplebucket ».

Avant de commencer à déplacer les données des employés dans des compartiments, assurez-vous qu'elles comportent des noms de colonnes tels que prénom, identifiant_de_poste, département, salaire et pays.

Nous chargeons ici des données dans samplebucket à partir de la table employees – la capture d'écran ci-dessous montre l'instruction INSERT OVERWRITE qui effectue la copie.

Instruction INSERT OVERWRITE copiant les lignes des employés dans la table samplebucket

Étape 3) Affichage des 4 compartiments créés à l'étape 1

L'affichage du répertoire de la table dans HDFS montre le résultat physique : quatre fichiers de données numérotés au lieu d'un seul.

Liste HDFS des quatre fichiers bucket créés dans le répertoire samplebucket

D'après la capture d'écran ci-dessus, nous pouvons voir que les données de la table des employés sont transférées dans les 4 compartiments créés à l'étape 1.

Partitionnement vs compartimentage Hive : principales différences

Ces deux fonctionnalités découpent une table en morceaux plus petits, mais à des niveaux différents du système de fichiers et répondent à des problèmes différents. Le tableau ci-dessous les compare.

Point de comparaison Partitionnement Seau
Unité créée Un répertoire par valeur clé Un fichier par compartiment de hachage
Déclaré avec PARTITIONNÉ PAR CLASSÉS PAR … DANS n SEAUX
Nombre de pièces Augmente avec le nombre de valeurs distinctes Corrigé lors de la création de la table
Colonne stockée dans les fichiers de données Non – la valeur se trouve dans le nom du répertoire Oui, la colonne reste une colonne normale
Type de colonne Meilleur Faible cardinalité, comme l'état, l'année ou le pays Cardinalité élevée, comme user_id ou transaction_id
Principal avantage L'élagage des partitions ignore les répertoires inutiles. Tailles de fichiers uniformes, échantillonnage bon marché et jointures côté carte

Ces deux méthodes ne sont pas concurrentes. Dans une architecture de production courante, une table de faits est partitionnée par date, puis divisée en groupes journaliers selon la clé de jointure. Ainsi, une requête est réduite à un répertoire, puis effectue des jointures de groupe en groupe à l'intérieur de celui-ci.

Quand utiliser le partitionnement, le bucketing ou les deux ?

Le choix entre ces options commence par la cardinalité de la colonne et la forme des requêtes qui liront la table.

  • Partition lorsque les requêtes filtrent presque toujours sur la même colonne à faible cardinalité, et lorsque le nombre de valeurs distinctes reste de l'ordre de centaines plutôt que de millions
  • Seau lorsque la colonne utile contient trop de valeurs distinctes pour servir de répertoire, ou lorsque la table est jointe ou échantillonnée de manière répétée sur cette colonne
  • Utilise les deux Pour les grandes tables de faits : partitionnez-les par date, puis regroupez-les au sein de chaque partition selon la clé de jointure.

Le problème à surveiller est celui des petits fichiers. Le partitionnement sur une colonne à cardinalité très élevée (un horodatage ou un identifiant client) génère des milliers de minuscules répertoires, chacun contenant un fichier bien inférieur à la taille d'un bloc HDFS. Cela augmente considérablement la mémoire du NameNode et ralentit chaque analyse, ce que le partitionnement visait précisément à éviter. Le bucketing permet d'éviter ce problème car le nombre de fichiers est limité par la définition de la table.

Le bucketing présente une limite : la structure n'est correcte que si chaque écriture la respecte. Le nombre de buckets déclaré lors de la création est une métadonnée ; par conséquent, une tâche qui écrit dans la table sans effectuer un clustering correct peut laisser des fichiers ne correspondant pas à la structure déclarée, et les échantillonnages ou jointures de buckets ultérieurs liront des lignes incorrectes.

FAQ

Exécutez la commande SHOW PARTITIONS nom_de_la_table dans l'interface Hive. Elle lit le metastore et affiche une ligne par répertoire de partition, ce qui est plus rapide que d'afficher le chemin du dépôt dans HDFS et confirme également que le metastore est synchronisé.

La commande ALTER TABLE table_name ADD PARTITION (state='Goa') crée un nouveau répertoire, et la commande ALTER TABLE table_name DROP PARTITION (state='Goa') le supprime.ping une partition gérée supprime ses données, tandis que la suppressionping Une commande externe efface uniquement l'entrée du métastore.

Par défaut, Hive limite les partitions dynamiques à 100 par nœud et 1 000 par instruction. Une clé comportant davantage de valeurs distinctes dépasse cette limite et interrompt la tâche. Augmentez les valeurs de `hive.exec.max.dynamic.partitions.pernode` et `hive.exec.max.dynamic.partitions`, ou choisissez une clé moins restrictive.

Non. Cette fonctionnalité était nécessaire dans Hive 0.x et 1.x pour que le nombre de réducteurs corresponde au nombre de compartiments. HIVE-12331 l'a supprimée dans Hive 2.0 ; le moteur calcule désormais le nombre de réducteurs et la colonne de regroupement à partir de la table.

La fonction TABLESAMPLE(BUCKET x OUT OF y ON column) lit uniquement les fichiers correspondants au lieu d'analyser l'ensemble des données. Comme les lignes sont hachées sur la même colonne lors de l'écriture, l'échantillon est reproductible et bien moins coûteux qu'un filtrage aléatoire des lignes.

Le fractionnement d'une table en milliers de petits fichiers gaspille la mémoire du NameNode et lance une tâche par fichier, ce qui ralentit les analyses. Ce problème survient généralement avec une clé de partition à cardinalité très élevée. Des clés plus grossières, le bucketing ou la compaction des fichiers permettent de le résoudre.

Oui. L'analyse des journaux de requêtes et les modèles d'apprentissage automatique d'outils tels que Cloudera Workload XM classent les colonnes par fréquence de filtrage, asymétrie et cardinalité, puis proposent une mise en page. Cette proposition doit encore être validée, car elle ne tient pas compte des charges de travail planifiées.

Copilot génère rapidement des instructions PARTITIONED BY et CLUSTERED BY à partir d'un commentaire, et les assistants agents peuvent générer un script de chargement complet. Vérifiez toujours le nombre de compartiments et la clé générés par rapport à la cardinalité réelle, car le modèle se base uniquement sur les noms.

Résumez cet article avec :