Réponses:
Le partitionnement des données est souvent utilisé pour répartir 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 avons affaire à une employee
table volumineuse et que nous exécutons souvent des requêtes avec des WHERE
clauses qui restreignent les résultats à un pays ou un département particulier. Pour une réponse de requête plus rapide, la table Hive peut être PARTITIONED BY (country STRING, DEPT STRING)
. Le partitionnement des tables modifie la façon dont Hive structure le stockage des données et Hive crée désormais des sous-répertoires reflétant la structure de partitionnement comme
... / employés / pays = ABC / DEPT = XYZ .
Si la requête limite les employés à partir de country=ABC
, il analysera uniquement le contenu d'un répertoire country=ABC
. 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 d'avoir trop de partitions est le grand nombre de fichiers et de répertoires Hadoop qui sont 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.
Le regroupement est une autre technique de décomposition des ensembles de données en parties plus faciles à gérer. Par exemple, supposons qu'une table utilisant date
comme partition de niveau supérieur et employee_id
comme partition de second niveau entraîne trop de petites partitions. Au lieu de cela, si nous compartimentons la table des employés et l'utilisons employee_id
comme colonne de compartimentage, 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
est bien supérieur au nombre de compartiments, chaque compartiment en aura plusieurs employee_id
. Lors de la création de la table, vous pouvez spécifier commeCLUSTERED BY (employee_id) INTO XX BUCKETS;
où XX est le nombre de seaux. Le bucketing présente plusieurs avantages. Le nombre de compartiments est fixe afin qu'il ne fluctue pas avec les données. Si deux tables sont regroupées employee_id
, Hive peut créer un échantillonnage logiquement correct. Le bucketing aide également à réaliser des jointures efficaces côté carte, etc.
Il manque quelques détails dans les explications précédentes. Pour mieux comprendre le fonctionnement du partitionnement et du compartimentage, vous devez examiner comment les données sont stockées dans la ruche. 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
puis la ruche stockera les données dans une hiérarchie de répertoires comme
/user/hive/warehouse/mytable/y=2015/m=12/d=02
Donc, vous devez être prudent lors du partitionnement, car si vous partitionnez par exemple par employee_id et que vous avez des millions d'employés, vous finirez par avoir 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", les pays du monde sont environ 300, donc la cardinalité serait d'environ 300. Pour un champ comme «timestamp_ms», qui change toutes les millisecondes, la cardinalité peut être de plusieurs milliards. En général, lorsque vous choisissez un champ pour le partitionnement, il ne devrait pas avoir une cardinalité élevée, car vous vous retrouverez avec beaucoup trop de répertoires dans votre système de fichiers.
Le clustering aka bucketing, d'autre part, se traduira par un nombre fixe de fichiers, puisque vous spécifiez le nombre de buckets. Ce que la ruche fera est de prendre le champ, de calculer un hachage et d'attribuer un enregistrement à ce compartiment. Mais que se passe-t-il si vous utilisez, disons, 256 compartiments et que le champ sur lequel vous effectuez un compartimentage a une faible cardinalité (par exemple, c'est un état américain, il ne peut donc 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. Ainsi, dans mon exemple de tableau, si vous souhaitez interroger uniquement à partir d'une certaine date, le partitionnement par année / mois / jour va réduire considérablement le montant d'E / S. Je pense que quelqu'un a également mentionné comment le bucketing peut accélérer les jointures avec d'autres tables qui ont exactement le même bucketing , donc dans mon exemple, si vous joignez deux tables sur le même employee_id, la ruche peut faire la jointure bucket par bucket (encore mieux s'ils sont déjà triés par employee_id car il va fusionner les parties qui sont déjà triées, ce qui fonctionne en temps linéaire aka O (n)).
Ainsi, le compartimentage fonctionne bien lorsque le champ a une cardinalité élevée et que les données sont uniformément réparties 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 une commande (année / mois / jour en est un bon exemple), alors que vous ne pouvez diviser que sur un seul champ .
Je pense que je suis en retard pour répondre à cette question, mais cela revient dans mon fil d'actualité.
Navneet a fourni une excellente réponse. Ajouter à cela visuellement.
Le partitionnement aide à éliminer les données, s'il est utilisé dans la clause WHERE, alors que le compartimentage aide à organiser les données de chaque partition en plusieurs fichiers, de sorte que le 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, name, server_date, some_col3, some_col4 et some_col5. Supposons que vous ayez partitionné la table sur server_date et compartimenté sur la colonne de nom dans 10 compartiments, votre structure de fichier ressemblera à quelque chose comme ci-dessous.
Ici server_date = xyz est la partition et 000 fichiers sont les buckets dans 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.
Partitionnement de la ruche:
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 stockez des informations sur des personnes dans le monde entier réparties dans plus de 196 pays couvrant environ 500 crores d'entrées. Si vous souhaitez interroger des 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 récupérer les 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 vérifiant simplement les données pour une seule partition de pays. La partition Hive crée un répertoire distinct pour une valeur de colonne (s).
Avantages:
Les inconvénients:
Seau de la ruche:
Le regroupement décompose les données en parties plus gérables ou égales.
Avec le partitionnement, il est possible que vous puissiez créer plusieurs petites partitions en fonction des valeurs de colonne. Si vous optez pour le compartimentage, vous limitez le nombre de compartiments pour stocker les données. Ce numéro est défini lors des scripts de création de table.
Avantages
Les inconvénients
Avant d'entrer dans le vif du sujet Bucketing
, nous devons comprendre ce que Partitioning
c'est. 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 les scénarios en temps réel, vous pouvez avoir des millions d'enregistrements.
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 sql ci-dessous, il doit analyser tous les enregistrements de la table, ce qui réduit les performances et augmente la surcharge.
select * from sales_table where product_id='P1'
Pour éviter une analyse complète de la table et pour lire uniquement les enregistrements associés, product_id='P1'
nous pouvons partitionner (diviser les fichiers de la table de la ruche) en plusieurs fichiers en fonction de la product_id
colonne. Ainsi, le fichier de la table de la ruche 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 analysera uniquement le product_id='P1'
fichier.
../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2
La syntaxe de création de la partition est donnée ci-dessous. Notez que nous ne devons pas utiliser la product_id
définition de colonne avec les colonnes non partitionnées dans la syntaxe ci-dessous. Cela ne devrait être que dans la partitioned by
clause.
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 du partitionnement. Autrement dit, il ne doit pas être utilisé pour les colonnes où le nombre de valeurs répétitives 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 ce cons
que j'ai mentionné dans la section de partitionnement. Cela doit être utilisé lorsqu'il y a très peu de valeurs répétitives 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 une Sales_Id
colonne pour le seau. Cela sera utile lorsque nous aurons besoin d'interroger la sales_id
colonne.
Vous trouverez ci-dessous la syntaxe du compartimentage.
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 davantage les données en quelques fichiers supplémentaires au-dessus des partitions.
Puisque nous avons spécifié des 3
buckets, il est divisé en 3 fichiers chacun pour chacun product_id
. Il utilise en interne modulo operator
pour déterminer dans quel seau chacun 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.
hashCode()
de la chaîne comme fonction de hachage? Le programmeur peut-il choisir la fonction de hachage?
La différence est que le compartimentage divise les fichiers par nom de colonne et le partitionnement divise les fichiers sous Par une valeur particulière dans la table
J'espère que je l'ai défini correctement
Il y a de bonnes réponses ici. Je voudrais rester bref pour mémoriser la différence entre la partition et les seaux.
Vous partitionnez généralement sur une colonne moins unique. Et le regroupement sur la colonne la plus unique.
Exemple si vous considérez la population mondiale avec le pays, le nom de la personne et son identifiant bio-métrique comme exemple. Comme vous pouvez le deviner, le champ de pays serait la colonne la moins unique et l'identifiant bio-métrique serait 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.
L'utilisation de partitions dans la table Hive est fortement recommandée pour les raisons ci-dessous -
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 entières pour toute requête que vous exécutez sur cette table. Le temps de réponse sera élevé par rapport aux autres approches où le partitionnement et le regroupement 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 fractionnant les données au sein de chaque partition. Voir l'option de regroupement ci-dessous.
Table Hive avec partition et compartimentage
Remarque: Créez une table de ruche ..... avec "CLUSTERED BY (Partiton_Column) dans 5 buckets
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 - Le regroupement créera plus de fichiers. Il peut y avoir un problème avec de nombreux petits fichiers dans certains cas spécifiques
J'espère que cela aidera !!