154 votes

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

Je sais que les deux opérations sont effectuées sur une colonne dans la table mais en quoi chaque opération est-elle différente.

278voto

Navneet Kumar Points 3642

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

.../employees/country=ABC/DEPT=XYZ.

Si une requête limite pour un employé du pays ABC, elle ne parcourra que le contenu d'un seul répertoire pays ABC. Cela peut améliorer considérablement les performances des requêtes, mais seulement si le schéma de partitionnement reflète des filtres communs. La fonction 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 d'avoir trop de partitions, c'est le grand nombre de fichiers et répertoires Hadoop créés inutilement et la surcharge de NameNode car il doit conserver toutes les métadonnées du système de fichiers en mémoire.

La mise en buckets est une autre technique pour décomposer les ensembles de données en parties plus gérables. Par exemple, supposons qu'une table utilise date comme partition de premier niveau et employee_id comme partition de deuxième niveau mène à trop de petites partitions. Au lieu de cela, si nous mettons la table des employés en buckets et utilisons employee_id en tant que colonne de mise en buckets, la valeur de cette colonne sera hashée par un nombre défini par l'utilisateur en buckets. Les enregistrements avec le même employee_id seront toujours stockés dans le même bucket. En créant la table, vous pouvez spécifier quelque chose comme CLUSTERED BY (employee_id) INTO XX BUCKETS; où XX est le nombre de buckets. La mise en buckets présente plusieurs avantages. Le nombre de buckets est fixe, il ne fluctue donc pas avec les données. Si deux tables sont mises en buckets par employee_id, Hive peut créer un échantillonnage logiquement correct. La mise en buckets aide également à réaliser des joints efficaces du côté du map, etc.

150voto

Roberto Congiu Points 2917

Il manque quelques détails dans les explications précédentes. Pour mieux comprendre le fonctionnement du partitionnement et du découpage en buckets, vous devriez regarder 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 par employee_id et que vous avez des millions d'employés, vous vous retrouverez avec des millions de répertoires dans votre système de fichiers. Le terme 'cardinalité' fait référence au nombre de valeurs possibles qu'un champ peut avoir. Par exemple, si vous avez un champ 'pays', il y a environ 300 pays dans le monde, donc la cardinalité serait d'environ 300. Pour un champ comme 'timestamp_ms', qui change chaque milliseconde, la cardinalité peut être de l'ordre du milliard. En général, lors du choix d'un champ pour le partitionnement, sa cardinalité ne devrait pas être élevée, car vous vous retrouveriez avec beaucoup trop de répertoires dans votre système de fichiers.

Le regroupement aka le découpage en buckets, d'autre part, produira un nombre fixe de fichiers, puisque vous spécifiez le nombre de buckets. Hive prendra le champ, calculera un hash et attribuera un enregistrement à ce bucket. Mais que se passe-t-il si vous utilisez disons 256 buckets et que le champ sur lequel vous découpez a une faible cardinalité (par exemple, c'est un état américain, donc il ne peut y avoir que 50 valeurs différentes) ? Vous aurez 50 buckets avec des données, et 206 buckets sans données.

Quelqu'un a déjà mentionné comment les partitions peuvent réduire considérablement la quantité de données que vous interrogez. Donc, dans mon exemple de table, si vous voulez interroger uniquement à partir d'une certaine date, le partitionnement par année/mois/jour va considérablement réduire le volume d'E/S. Je crois que quelqu'un a également mentionné comment le découpage en buckets peut accélérer les jointures avec d'autres tables qui ont exactement le même découpage en buckets, donc dans mon exemple, si vous faites une jointure sur deux tables avec le même employee_id, Hive peut faire la jointure bucket par bucket (encore mieux si elles sont déjà triées par employee_id puisqu'il va fusionner des parties déjà triées, ce qui fonctionne en temps linéaire aka O(n)).

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

De plus, vous pouvez partitionner sur plusieurs champs, avec un ordre (année/mois/jour est un bon exemple), alors que vous ne pouvez découper en buckets que sur un seul champ.

24voto

Sarath Avanavu Points 85

Avant de parler de Bucketing, nous devons comprendre ce qu'est la Partitioning. Prenons le tableau ci-dessous comme exemple. Notez que je n'ai donné que 12 enregistrements dans l'exemple ci-dessous pour une compréhension de niveau débutant. Dans des scénarios réels, vous pourriez avoir des millions d'enregistrements.

entrez la description de l'image ici

PARTITIONING
---------------------
Partitioning est utilisé pour améliorer les performances lors de l'interrogation des données. Par exemple, dans le tableau ci-dessus, si nous écrivons le SQL ci-dessous, il doit scanner tous les enregistrements de la table, ce qui réduit les performances et augmente la charge.

select * from sales_table where product_id='P1'

Pour éviter le balayage complet de la table et ne lire que les enregistrements liés à product_id='P1', nous pouvons partitionner (diviser les fichiers de la table hive) en plusieurs fichiers en fonction de la colonne product_id. Ainsi, le fichier de la table hive sera divisé en deux fichiers, l'un avec product_id='P1' et l'autre avec product_id='P2'. Maintenant, lorsque nous exécutons la requête ci-dessus, il ne scannera que le fichier product_id='P1'.

../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 devons être très prudents lors de la partition. C'est-à-dire qu'il ne doit pas être utilisé pour les colonnes où le nombre de valeurs répétées est très faible (en particulier les colonnes de clé primaire) car cela augmente le nombre de fichiers partitionnés et augmente la charge pour le Name node.

BUCKETING
------------------
Bucketing est utilisé pour surmonter les inconvénients que j'ai mentionnés dans la section de partitioning. Cela devrait être utilisé lorsqu'il y a très peu de valeurs répétées dans une colonne (par exemple, colonne de clé primaire). Cela est similaire au concept d'index sur une 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 devons interroger la colonne sales_id.

Voici la syntaxe pour le bucketing.

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 diviser les données en quelques fichiers supplémentaires en plus des partitions.

entrez la description de l'image ici

Étant donné que nous avons spécifié 3 buckets, il est divisé en 3 fichiers pour chaque product_id. Il utilise internalement l'opérateur modulo pour déterminer dans quel bucket 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'est-à-dire, 2%3=2),sales_id=3 sera stocké dans le fichier 000000_0 (c'est-à-dire, 3%3=0) etc.

19voto

Priyesh Points 21

Je pense que je suis en retard pour répondre à cette question, mais elle continue à apparaître dans mon fil d'actualité.

Navneet a fourni une excellente réponse. Ajoutons-y une dimension visuelle.

La partition permet d'éliminer des données, si elle est utilisée dans la clause WHERE, tandis que le bucketing permet d'organiser les données de chaque partition dans plusieurs fichiers, de sorte que le même ensemble de données soit toujours écrit dans le même bucket. Cela aide beaucoup dans la jointure des colonnes.

Supposons que vous ayez une table avec cinq colonnes : name, server_date, some_col3, some_col4 et some_col5. Supposons que vous ayez partitionné la table sur server_date et mis en buckets la colonne name dans 10 buckets, la structure du fichier ressemblera à quelque chose comme ci-dessous.

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

Ici, server_date=xyz est la partition et les fichiers 000 sont les buckets de chaque partition. Les buckets sont calculés en fonction de certaines fonctions de hachage, donc les lignes avec name=Sandy iront toujours dans le même bucket.

18voto

Ravindra babu Points 5571

Partitionnement Hive:

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

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

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 "Cité du Vatican" se fait 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 telles que le regroupement parmi un volume élevé de données prennent quand même beaucoup de temps à s'exécuter. Par exemple, le regroupement de la population de la Chine prendra plus de temps que le regroupement de la population de la Cité du Vatican. La partition ne résout pas le problème de réactivité en cas de déséquilibre des données en faveur d'une valeur de partition particulière.

Bucketing Hive:

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

Avec le partitionnement, il est possible de créer de multiples petites partitions en fonction des valeurs de colonnes. Si vous optez pour le bucketing, vous limitez le nombre de seaux pour stocker les données. Ce nombre est défini lors des scripts de création de table.

Avantages

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

Inconvénients

  1. Vous pouvez définir le nombre de seaux lors de la création de table, mais le chargement de volumes de données égaux doit être fait manuellement par les programmeurs.

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