web-dev-qa-db-fra.com

Quelle est la différence entre le partitionnement et le bucketing d'une table dans Hive?

Je sais que les deux sont effectuées sur une colonne du tableau, mais en quoi chaque opération est différente.

119
NishM

Partitionnement les données sont souvent utilisées pour répartir la charge horizontalement, ce qui présente des avantages en termes de performances et facilite l'organisation des données de manière logique. Exemple : si nous traitons avec une grande table employee et exécutons souvent des requêtes avec les clauses WHERE qui limitent les résultats à une pays ou département particulier. Pour une réponse plus rapide à la requête, la table Hive peut être PARTITIONED BY (country STRING, DEPT STRING). Les tables de partitionnement modifient la manière dont Hive structure le stockage de données et Hive créera désormais des sous-répertoires reflétant la structure de partitionnement comme

.../employés/ pays = ABC/DEPT = XYZ .

Si la requête limite le nombre d'employés de country=ABC, seul le contenu d'un répertoire country=ABC sera analysé. Cela peut considérablement améliorer les performances des requêtes, mais uniquement si le schéma de partitionnement reflète un filtrage commun. La fonctionnalité de partitionnement est très utile dans Hive, cependant, une conception qui crée trop de partitions peut optimiser certaines requêtes, mais être préjudiciable pour d'autres requêtes importantes. Un autre inconvénient est le trop grand nombre de partitions et le grand nombre de fichiers et de répertoires Hadoop créés inutilement et surchargés en NameNode car il doit conserver toutes les métadonnées du système de fichiers en mémoire.

Bucketing est une autre technique permettant de décomposer des ensembles de données en parties plus faciles à gérer. Par exemple, supposons une table utilisant date en tant que partition de niveau supérieur et employee_id en tant que partition de second niveau entraîne trop de petites partitions. Au lieu de cela, si nous divisons la table employee et utilisons employee_id en tant que colonne de compartiment, la valeur de cette colonne sera hachée par un nombre défini par l'utilisateur dans des compartiments. Les enregistrements avec le même employee_id seront toujours stockés dans le même compartiment. En supposant que le nombre de employee_id soit beaucoup plus grand que le nombre de compartiments, chaque compartiment aura plusieurs employee_id. Lors de la création du tableau, vous pouvez spécifier comme CLUSTERED BY (employee_id) INTO XX BUCKETS; où XX est le nombre de compartiments. Le seau présente plusieurs avantages. Le nombre de compartiments est fixe afin qu'il ne fluctue pas avec les données. Si deux tables sont classées par employee_id, Hive peut créer un échantillonnage logiquement correct. Le Bucketing aide également à réaliser des jointures efficaces au niveau de la carte, etc.

230
Navneet Kumar

Il manque quelques détails dans les explications précédentes. Pour mieux comprendre le fonctionnement du partitionnement et du compartiment, vous devez examiner comment les données sont stockées dans Hive. Disons que vous avez une table

CREATE TABLE mytable ( 
         name string,
         city string,
         employee_id int ) 
PARTITIONED BY (year STRING, month STRING, day STRING) 
CLUSTERED BY (employee_id) INTO 256 BUCKETS

alors Hive stockera les données dans une hiérarchie de répertoires comme

/user/Hive/warehouse/mytable/y=2015/m=12/d=02

Il faut donc faire attention lors du partitionnement, car si vous partitionnez par exemple employee_id et que vous avez des millions d’employés, vous aurez des millions de répertoires dans votre système de fichiers. Le terme "cardinalité" désigne le nombre de valeurs possibles qu'un champ peut avoir. Par exemple, si vous avez un champ "pays", le nombre de pays dans le monde est d'environ 300, donc la cardinalité serait d'environ 300. Pour un champ tel que 'timestamp_ms', qui change toutes les millisecondes, la cardinalité peut représenter des milliards. En général, lorsque vous choisissez un champ pour le partitionnement, il ne devrait pas avoir une cardinalité élevée, car vous allez vous retrouver avec trop de répertoires dans votre système de fichiers.

La mise en cluster, ou compartiment, en revanche, entraînera un nombre fixe de fichiers, car vous spécifiez le nombre de compartiments. Ce que Hive fera, c'est prendre le champ, calculer un hachage et attribuer un enregistrement à ce compartiment. Mais que se passe-t-il si vous utilisez, par exemple, 256 compartiments et que le champ sur lequel vous vous situez a une cardinalité faible (par exemple, il s’agit d’un État américain, donc ne peut comporter que 50 valeurs différentes)? Vous aurez 50 compartiments avec des données et 206 compartiments sans données.

Quelqu'un a déjà expliqué comment les partitions peuvent considérablement réduire la quantité de données que vous interrogez. Ainsi, dans mon exemple de tableau, si vous souhaitez interroger uniquement à partir d'une date donnée, le partitionnement par année/mois/jour va réduire considérablement le montant des entrées-sorties. Je pense que quelqu'un a également mentionné comment un seau peut accélérer les jointures avec d'autres tables qui ont exactement le même seau , donc dans mon exemple, si vous rejoignez deux tables sur le même employee_id, Hive peut faire le compartiment de jointure par compartiment (encore mieux s’ils sont déjà triés par employee_id car ils vont trier les pièces mergesort déjà triées, ce qui fonctionne en temps linéaire aka O(n)).

Ainsi, le godet fonctionne bien lorsque le champ a une cardinalité élevée et que les données sont réparties uniformément entre les compartiments. Le partitionnement fonctionne mieux lorsque la cardinalité du champ de partitionnement n'est pas trop élevée.

En outre, vous pouvez partitionner sur plusieurs champs , avec un ordre (année/mois/jour est un bon exemple), tandis que vous ne pouvez vous connecter qu’à un seul champ .

121
Roberto Congiu

Je pense que je suis en retard pour répondre à cette question, mais cela continue à apparaître dans mon flux.

Navneet a fourni une excellente réponse. Ajouter à cela visuellement.

Le partitionnement contribue à l'élimination des données, s'il est utilisé dans la clause WHERE, tandis que le compartiment aide à organiser les données de chaque partition en plusieurs fichiers, de sorte qu'un même ensemble de données est toujours écrit dans le même compartiment. Aide beaucoup à joindre des colonnes.

Supposons que vous ayez une table avec cinq colonnes, nom, date_serveur, some_col3, some_col4 et some_col5. Supposons que vous ayez partitionné la table sur la colonne server_date et que vous ayez placé un seau sur la colonne nom dans 10 compartiments. Votre structure de fichier ressemblera à ce qui suit.

  1. date_serveur = xyz
    • 00000_0
    • 00001_0
    • 00002_0
    • ........
    • 00010_0

Ici server_date = xyz est la partition et les fichiers sont les compartiments de chaque partition. Les compartiments étant calculés en fonction de certaines fonctions de hachage, les lignes avec name = Sandy seront toujours dans le même compartiment.

18
Priyesh

partitionnement de la ruche:

La partition divise une grande quantité de données en plusieurs tranches en fonction de la valeur d'une colonne de table.

Supposons que vous stockez des informations sur des personnes dans le monde entier, réparties dans plus de 196 pays et couvrant environ 500 millions d'entrées. Si vous souhaitez interroger des personnes d'un pays particulier (la Cité du Vatican), en l'absence de partitionnement, vous devez analyser les 500 crores d'entrées, même pour extraire des milliers d'entrées d'un pays. Si vous partitionnez la table en fonction des pays, vous pouvez affiner le processus d'interrogation en ne vérifiant que les données d'une seule partition de pays. La partition Hive crée un répertoire distinct pour une valeur de colonne.

Avantages:

  1. Répartir la charge d'exécution horizontalement
  2. Exécution plus rapide des requêtes en cas de partition avec un faible volume de données. par exemple. Obtenir la population de "Vatican city" revient très rapidement au lieu de rechercher toute la population du monde.

Inconvénients:

  1. Possibilité de créer trop de petites partitions - trop de répertoires.
  2. Efficace pour les données à faible volume pour une partition donnée. Mais certaines requêtes comme grouper par grand volume de données prennent encore beaucoup de temps à s'exécuter. par exemple. Le regroupement de la population chinoise prendra beaucoup de temps par rapport au regroupement de la population dans la cité du Vatican. La partition ne résout pas le problème de réactivité en cas de décalage des données vers une valeur de partition particulière.

Ruche Bucketing:

Le Bucketing décompose les données en parties plus gérables ou égales.

Avec le partitionnement, il est possible de créer plusieurs petites partitions en fonction des valeurs de colonne. Si vous optez pour un compartiment, vous limitez le nombre de compartiments pour stocker les données. Ce nombre est défini lors des scripts de création de table.

Pros

  1. En raison de volumes égaux de données dans chaque partition, les jointures du côté Carte seront plus rapides.
  2. Réponse de requête plus rapide comme le partitionnement

Contre

  1. Vous pouvez définir le nombre de compartiments lors de la création de la table, mais le chargement d'un volume égal de données doit être effectué manuellement par les programmeurs.
15
Ravindra babu

La différence est compartiment divise les fichiers par Nom de colonne, et partitionnement divise les fichiers sous Par une valeur particulière dans la table

Si tout va bien je l'ai défini correctement

5
uriya harel

Avant d’entrer dans Bucketing, nous devons comprendre ce que Partitioning est. Prenons le tableau ci-dessous à titre d'exemple. Notez que je n'ai donné que 12 enregistrements dans l'exemple ci-dessous pour une compréhension du niveau débutant. Dans des scénarios en temps réel, vous pourriez avoir des millions d'enregistrements.

enter image description here



PARTITIONNEMENT
---------------------
Partitioning est utilisé pour obtenir des performances lors de l'interrogation des données. Par exemple, dans le tableau ci-dessus, si nous écrivons le code sql ci-dessous, il doit analyser tous les enregistrements de la table, ce qui réduit les performances et augmente les frais généraux.

select * from sales_table where product_id='P1'

Pour éviter l'analyse complète de la table et lire uniquement les enregistrements liés à product_id='P1', nous pouvons partitionner (les fichiers de la table Hive fractionnés) en plusieurs fichiers en fonction de la colonne product_id. De ce fait, le fichier de la table Hive sera divisé en deux fichiers, l'un avec product_id='P1' et l'autre avec product_id='P2'. Désormais, lorsque nous exécuterons la requête ci-dessus, seul le fichier product_id='P1' sera analysé.

../Hive/warehouse/sales_table/product_id=P1
../Hive/warehouse/sales_table/product_id=P2

La syntaxe pour créer la partition est donnée ci-dessous. Notez que nous ne devrions pas utiliser la définition de colonne product_id avec les colonnes non partitionnées dans la syntaxe ci-dessous. Cela devrait être uniquement dans la clause partitioned by.

create table sales_table(sales_id int,trans_date date, amount int) 
partitioned by (product_id varchar(10))

Inconvénients : Nous devrions faire très attention lors du partitionnement. Autrement dit, il ne doit pas être utilisé pour les colonnes où le nombre de valeurs répétées est très inférieur (en particulier les colonnes de clé primaire), car il augmente le nombre de fichiers partitionnés et augmente la surcharge pour le Name node.



BUCKETING
------------------
Bucketing est utilisé pour surmonter le cons que j'ai mentionné dans la section sur le partitionnement. Cela devrait être utilisé quand il y a très peu de valeurs répétées dans une colonne (exemple - colonne de clé primaire). Ceci est similaire au concept d'index sur la colonne de clé primaire dans le SGBDR. Dans notre tableau, nous pouvons prendre la colonne Sales_Id pour le Bucketing. Cela sera utile lorsque nous aurons besoin d'interroger la colonne sales_id.

Vous trouverez ci-dessous la syntaxe pour le seau.

create table sales_table(sales_id int,trans_date date, amount int) 
partitioned by (product_id varchar(10)) Clustered by(Sales_Id) into 3 buckets

Ici, nous allons encore diviser les données en quelques fichiers supplémentaires au-dessus des partitions.

enter image description here

Puisque nous avons spécifié les compartiments 3, il est divisé en 3 fichiers chacun pour chaque product_id. Il utilise en interne modulo operator pour déterminer dans quel compartiment chaque sales_id doit être stocké. Par exemple, pour le product_id='P1', le sales_id=1 sera stocké dans le fichier 000001_0 (c'est-à-dire, 1% 3 = 1). , sales_id=2 sera stocké dans le fichier 000002_0 (c.-à-d. 2% 3 = 2), sales_id=3 sera stocké dans 000000_0 fichier (c'est-à-dire 3% 3 = 0) etc.

4
Sarath Avanavu

L'utilisation de partitions dans la table Hive est fortement recommandée pour les raisons ci-dessous -

  • L'insertion dans la table Hive devrait être plus rapide (car elle utilise plusieurs threads pour écrire des données sur des partitions)
  • Les requêtes de la table Hive doivent être efficaces avec une faible latence.

Exemple :-

Supposons que le fichier d'entrée (100 Go) est chargé dans temp-Hive-table et qu'il contient des données bancaires provenant de différentes zones géographiques.

table Hive sans partition

Insert into Hive table Select * from temp-Hive-table

/Hive-table-path/part-00000-1  (part size ~ hdfs block size)
/Hive-table-path/part-00000-2
....
/Hive-table-path/part-00000-n

Le problème avec cette approche est - Il analysera les données complètes pour toutes les requêtes que vous exécuterez sur cette table. Le temps de réponse sera élevé par rapport aux autres approches où le partitionnement et la segmentation sont utilisés.

table Hive avec partition

Insert into Hive table partition(country) Select * from temp-Hive-table

/Hive-table-path/country=US/part-00000-1       (file size ~ 10 GB)
/Hive-table-path/country=Canada/part-00000-2   (file size ~ 20 GB)
....
/Hive-table-path/country=UK/part-00000-n       (file size ~ 5 GB)

Avantages - Ici, on peut accéder aux données plus rapidement lorsqu'il s'agit d'interroger des données pour des transactions géographiques spécifiques. Inconvénients - L'insertion/interrogation de données peut être encore améliorée en séparant les données dans chaque partition. Voir l'option de Bucketing ci-dessous.

Table de ruche avec partition et sea

Note: Créer une table Hive ..... avec "CLUSTERED BY (Partiton_Column) dans 5 compartiments

Insert into Hive table partition(country) Select * from temp-Hive-table

/Hive-table-path/country=US/part-00000-1       (file size ~ 2 GB)
/Hive-table-path/country=US/part-00000-2       (file size ~ 2 GB)
/Hive-table-path/country=US/part-00000-3       (file size ~ 2 GB)
/Hive-table-path/country=US/part-00000-4       (file size ~ 2 GB)
/Hive-table-path/country=US/part-00000-5       (file size ~ 2 GB)

/Hive-table-path/country=Canada/part-00000-1   (file size ~ 4 GB)
/Hive-table-path/country=Canada/part-00000-2   (file size ~ 4 GB)
/Hive-table-path/country=Canada/part-00000-3   (file size ~ 4 GB)
/Hive-table-path/country=Canada/part-00000-4   (file size ~ 4 GB)
/Hive-table-path/country=Canada/part-00000-5   (file size ~ 4 GB)

....
/Hive-table-path/country=UK/part-00000-1       (file size ~ 1 GB)
/Hive-table-path/country=UK/part-00000-2       (file size ~ 1 GB)
/Hive-table-path/country=UK/part-00000-3       (file size ~ 1 GB)
/Hive-table-path/country=UK/part-00000-4       (file size ~ 1 GB)
/Hive-table-path/country=UK/part-00000-5       (file size ~ 1 GB)

Avantages - Insertion plus rapide. Requête plus rapide.

Inconvénients - Bucketing créera plus de fichiers. Il pourrait y avoir un problème avec beaucoup de petits fichiers dans certains cas spécifiques

J'espère que ça va aider !!

0
NoName

Il y a d'excellentes réponses ici. Je voudrais rester bref pour mémoriser la différence entre partition et compartiments.

Vous partitionnez généralement sur une colonne moins unique. Et un compartiment sur la colonne la plus unique.

Exemple si vous considérez Population mondiale avec le pays, le nom de la personne et son identifiant biométrique à titre d'exemple. Comme vous pouvez le deviner, la zone pays serait la colonne la moins unique et l'id bio-métrique, la colonne la plus unique. Donc, idéalement, vous auriez besoin de partitionner la table par pays et de la classer par identifiant bio-métrique.

0
SVK