Was ist der Unterschied zwischen dem Partitionieren und Bucketing einer Tabelle in Hive?

129

Ich weiß, dass beide für eine Spalte in der Tabelle ausgeführt werden, aber wie unterscheidet sich jede Operation?

NishM
quelle

Antworten:

247

Das Partitionieren von Daten wird häufig zum horizontalen Verteilen von Lasten verwendet. Dies hat Leistungsvorteile und hilft bei der logischen Organisation von Daten. Beispiel : Wenn es sich um eine große employeeTabelle handelt und häufig Abfragen mit WHEREKlauseln ausgeführt werden, die die Ergebnisse auf ein bestimmtes Land oder eine bestimmte Abteilung beschränken. Für eine schnellere Abfrageantwort kann Hive-Tabelle sein PARTITIONED BY (country STRING, DEPT STRING). Durch das Partitionieren von Tabellen wird geändert, wie Hive den Datenspeicher strukturiert, und Hive erstellt jetzt Unterverzeichnisse, die die Partitionierungsstruktur widerspiegeln

... / Mitarbeiter / Land = ABC / DEPT = XYZ .

Wenn die Abfrage für Mitarbeiter begrenzt ist country=ABC, wird nur der Inhalt eines Verzeichnisses gescannt country=ABC. Dies kann die Abfrageleistung erheblich verbessern, jedoch nur, wenn das Partitionierungsschema die allgemeine Filterung widerspiegelt. Die Partitionierungsfunktion ist in Hive sehr nützlich. Ein Entwurf, der zu viele Partitionen erstellt, kann jedoch einige Abfragen optimieren, für andere wichtige Abfragen jedoch nachteilig sein. Ein weiterer Nachteil ist, dass zu viele Partitionen die große Anzahl von Hadoop-Dateien und -Verzeichnissen sind, die unnötig erstellt werden und zu viel Aufwand für NameNode führen, da alle Metadaten für das Dateisystem im Speicher bleiben müssen.

Bucketing ist eine weitere Technik zum Zerlegen von Datensätzen in besser verwaltbare Teile. Angenommen, eine Tabelle, die dateals Partition der obersten Ebene und employee_idals Partition der zweiten Ebene verwendet wird, führt zu zu vielen kleinen Partitionen. Wenn wir stattdessen die Mitarbeitertabelle employee_idin Buckets speichern und als Bucketing-Spalte verwenden, wird der Wert dieser Spalte durch eine benutzerdefinierte Zahl in Buckets gehasht. Datensätze mit demselben employee_id werden immer im selben Bucket gespeichert. Angenommen, die Anzahl employee_idist viel größer als die Anzahl der Eimer, dann hat jeder Eimer viele employee_id. Beim Erstellen einer Tabelle können Sie wie angebenCLUSTERED BY (employee_id) INTO XX BUCKETS;Dabei ist XX die Anzahl der Eimer. Schaufeln hat mehrere Vorteile. Die Anzahl der Buckets ist festgelegt, damit sie nicht mit den Daten schwankt. Wenn zwei Tabellen mit einem Bucket versehen sind employee_id, kann Hive eine logisch korrekte Stichprobe erstellen. Das Bucketing hilft auch bei der Durchführung effizienter kartenseitiger Verknüpfungen usw.

Navneet Kumar
quelle
4
Danke Navneet. Können Sie jedoch erläutern, wie das Bucketing bei der Partitionierung geschieht? Angenommen, wenn wir in der CLUSED BY-Klausel 32 Buckets angeben und die CREATE TABLE-Anweisung auch die Partitioning-Klausel enthält, wie werden Partitionen und Buckets zusammen verwaltet? Ist die Anzahl der Partitionen auf 32 begrenzt? ODER für jede Partition werden 32 Buckets erstellt? Ist jeder Bucket eine HDFS-Datei?
SGSI
12
Ein Hive-Tisch kann sowohl partitioniert als auch Bucketing sein. Basierend auf Ihrer Partitionsklausel werden für jede Partition 32 Buckets erstellt. Ja HDFS-Datei.
Navneet Kumar
7
@sgsi Partition ist ein Ordner, Bucket ist eine Datei.
Links zum
12
Diese Antwort stammt aus dem Text von Programming Hive (O'Reilly, 2012).
Ianmcook
1
Ich fand diesen Link nützlich. Es enthält Informationen, die dieser Antwort mehr Wert verleihen. linkedin.com/pulse/…
Alex Raj Kaliamoorthy
129

In den vorherigen Erläuterungen fehlen einige Details. Um besser zu verstehen, wie Partitionierung und Bucketing funktionieren, sollten Sie sich ansehen, wie Daten in Hive gespeichert werden. Angenommen, Sie haben einen Tisch

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

dann speichert hive Daten in einer Verzeichnishierarchie wie

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

Sie müssen also beim Partitionieren vorsichtig sein, denn wenn Sie beispielsweise nach employee_id partitionieren und Millionen von Mitarbeitern haben, haben Sie am Ende Millionen von Verzeichnissen in Ihrem Dateisystem. Der Begriff " Kardinalität " bezieht sich auf die Anzahl der möglichen Werte, die ein Feld haben kann. Wenn Sie beispielsweise ein Feld "Land" haben, sind die Länder der Welt ungefähr 300, sodass die Kardinalität ~ 300 beträgt. Für ein Feld wie 'timestamp_ms', das sich jede Millisekunde ändert, kann die Kardinalität Milliarden betragen. Wenn Sie ein Feld für die Partitionierung auswählen, sollte es im Allgemeinen keine hohe Kardinalität aufweisen, da Sie am Ende viel zu viele Verzeichnisse in Ihrem Dateisystem haben.

Clustering, auch Bucketing genannt, führt zu einer festen Anzahl von Dateien, da Sie die Anzahl der Buckets angeben. Was Hive tun wird, ist das Feld zu nehmen, einen Hash zu berechnen und diesem Bucket einen Datensatz zuzuweisen. Aber was passiert, wenn Sie beispielsweise 256 Buckets verwenden und das Feld, auf dem Sie Buckets erstellen, eine geringe Kardinalität aufweist (z. B. ein US-Bundesstaat, also nur 50 verschiedene Werte)? Sie haben 50 Buckets mit Daten und 206 Buckets ohne Daten.

Jemand hat bereits erwähnt, wie Partitionen die Datenmenge, die Sie abfragen, drastisch reduzieren können. Wenn Sie in meiner Beispieltabelle nur ab einem bestimmten Datum abfragen möchten, wird durch die Partitionierung nach Jahr / Monat / Tag die Anzahl der E / A-Vorgänge drastisch reduziert. Ich denke, dass jemand auch erwähnt hat, wie das Bucketing Verknüpfungen mit anderen Tabellen beschleunigen kann , die genau das gleiche Bucketing haben. Wenn Sie also in meinem Beispiel zwei Tabellen mit derselben employee_id verbinden, kann hive den Join Bucket für Bucket ausführen (noch besser) Wenn sie bereits nach employee_id sortiert sind, werden bereits sortierte Teile zusammengeführt, was in linearer Zeit (auch bekannt als O (n)) funktioniert.

Bucketing funktioniert also gut, wenn das Feld eine hohe Kardinalität aufweist und die Daten gleichmäßig auf die Buckets verteilt sind. Die Partitionierung funktioniert am besten, wenn die Kardinalität des Partitionierungsfelds nicht zu hoch ist.

Außerdem können Sie sich auf mehrere Felder unterteilen , mit einem Auftrag (Jahr / Monat / Tag ist ein gutes Beispiel), während Sie nur ein Feld Eimer auf kann .

Roberto Congiu
quelle
Können Sie bitte das CLUSTERED-BY-Verhalten mit SORTED-BY in einem Beispiel erläutern? Gemäß meinem Beispiel habe ich festgestellt, dass SORTED-BY nichts tut. Vermisse ich etwas?
Jagadish Talluri
2
CLUSTERED BY x, y ist wie das Schreiben von DISTRIBUTE BY x, y SORT BY x, y (siehe cwiki.apache.org/confluence/display/Hive/… ), sodass das Hinzufügen von SORT BY zu CLUSTERED BY keine Auswirkung hat.
Roberto Congiu
Interessanterweise stimme ich der Verwendung in ausgewählten Abfragen zu. Aber ich habe mich gefragt, warum Benutzer in der Anweisung zur Tabellenerstellung Clustered by und Sorted by verwenden. Wenn SORTED BY in DDL keine Bedeutung hat, warum ist dieses Schlüsselwort dann vorhanden? Hab das nicht verstanden.
Jagadish Talluri
SORTED BY soll mit DISTRIBUTED BY verwendet werden. Beispielsweise möchten Sie möglicherweise nach Benutzer-ID verteilen und nach Zeit innerhalb des Buckets sortieren. CLUSTER BY ist nur eine Abkürzung, wenn die Klausel in SORTED BY und DISTRIBUTED BY identisch ist. Ich kann nur daran denken, ob Sie nach x, y verteilen und nach x, y und z sortieren
Roberto Congiu
Ich bin mir nicht sicher, was Sie unter "Sie können nur auf einem Feld arbeiten" verstehen. Ich denke, es ist möglich, nach mehreren Feldern zu suchen. Die Hashing-Funktion nimmt einfach alle Felder und kombiniert sie.
Istvan
18

Ich glaube, ich bin spät dran, diese Frage zu beantworten, aber sie taucht immer wieder in meinem Feed auf.

Navneet hat eine hervorragende Antwort geliefert. Optisch hinzufügen.

Partitionierung hilft bei der Eliminierung von Daten, wenn sie in der WHERE-Klausel verwendet wird, wobei Bucketing beim Organisieren von Daten in jeder Partition in mehreren Dateien hilft, sodass immer derselbe Datensatz in denselben Bucket geschrieben wird. Hilft sehr beim Zusammenfügen von Spalten.

Angenommen, Sie haben eine Tabelle mit fünf Spalten: name, server_date, some_col3, some_col4 und some_col5. Angenommen, Sie haben die Tabelle partitioniert server_date und auf bucketed Name Spalte in 10 Eimer, wird Ihre Dateistruktur in etwa so aussehen unten.

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

Hier ist server_date = xyz die Partition und 000 Dateien sind die Buckets in jeder Partition. Buckets werden basierend auf einigen Hash-Funktionen berechnet, sodass Zeilen mit name = Sandy immer in denselben Bucket verschoben werden.

Priyesh
quelle
2
Laut Roberto in der obigen Antwort wäre server_date ein schlechtes Beispiel für die Partitionierung, da der Kardinalitätswert sehr hoch ist. Und so werden Sie am Ende zu viele Ordner in HDFS haben.
Gaurang Shah
Als Beispiel wird hier server_date genannt. In der realen Welt erfolgt die Partition im Allgemeinen wie von Roberto dargestellt, indem das Datum in Jahr / Monat / Tag unterteilt wird. Das ist wie es sein sollte.
Priyesh
17

Hive Partitioning:

Die Partition unterteilt eine große Datenmenge basierend auf dem Wert einer Tabellenspalte in mehrere Slices.

Angenommen, Sie speichern Informationen von Menschen auf der ganzen Welt in über 196 Ländern, die sich über rund 500 Millionen Einträge erstrecken. Wenn Sie Personen aus einem bestimmten Land (Vatikanstadt) ohne Partitionierung abfragen möchten, müssen Sie alle 500 Millionen Einträge scannen, um sogar tausend Einträge eines Landes abzurufen. Wenn Sie die Tabelle nach Ländern partitionieren, können Sie den Abfrageprozess optimieren, indem Sie nur die Daten für nur eine Länderpartition überprüfen. Die Hive-Partition erstellt ein separates Verzeichnis für einen Spaltenwert.

Vorteile:

  1. Verteilungslast horizontal verteilen
  2. Schnellere Ausführung von Abfragen bei Partition mit geringem Datenvolumen. zB Holen Sie sich die Bevölkerung aus " Vatikanstadt " kehrt sehr schnell zurück, anstatt die gesamte Bevölkerung der Welt zu durchsuchen.

Nachteile:

  1. Möglichkeit zu vieler kleiner Partitionserstellungen - zu viele Verzeichnisse.
  2. Wirksam für Daten mit geringem Datenvolumen für eine bestimmte Partition. Die Ausführung einiger Abfragen wie Gruppieren nach hohem Datenvolumen dauert jedoch noch lange. zB Die Gruppierung der Bevölkerung Chinas wird im Vergleich zur Gruppierung der Bevölkerung in der Vatikanstadt lange dauern. Die Partition löst nicht das Problem der Reaktionsfähigkeit, wenn Daten in Richtung eines bestimmten Partitionswerts verschoben werden.

Hive Bucketing:

Durch das Bucketing werden Daten in besser verwaltbare oder gleiche Teile zerlegt.

Bei der Partitionierung besteht die Möglichkeit, dass Sie mehrere kleine Partitionen basierend auf Spaltenwerten erstellen können. Wenn Sie sich für das Bucketing entscheiden, beschränken Sie die Anzahl der Buckets zum Speichern der Daten. Diese Nummer wird bei Tabellenerstellungsskripten definiert.

Vorteile

  1. Aufgrund des gleichen Datenvolumens in jeder Partition sind Verknüpfungen auf der Kartenseite schneller.
  2. Schnellere Abfrageantwort wie Partitionierung

Nachteile

  1. Sie können die Anzahl der Buckets während der Tabellenerstellung festlegen, das Laden des gleichen Datenvolumens muss jedoch manuell von den Programmierern durchgeführt werden.
Ravindra Babu
quelle
9

Bevor Bucketingwir darauf eingehen, müssen wir verstehen, was Partitioningist. Nehmen wir als Beispiel die folgende Tabelle. Beachten Sie, dass ich im folgenden Beispiel nur 12 Datensätze angegeben habe, um das Verständnis für Anfänger zu verbessern. In Echtzeitszenarien verfügen Sie möglicherweise über Millionen von Datensätzen.

Geben Sie hier die Bildbeschreibung ein



PARTITIONIERUNG
---------------------
Partitioning wird verwendet, um die Leistung beim Abfragen der Daten zu erhalten. Wenn wir beispielsweise in der obigen Tabelle die folgende SQL schreiben, müssen alle Datensätze in der Tabelle gescannt werden, was die Leistung verringert und den Overhead erhöht.

select * from sales_table where product_id='P1'

Um einen vollständigen Tabellenscan zu vermeiden und nur die zugehörigen Datensätze zu lesen, können product_id='P1'wir die Dateien der Hive-Tabelle basierend auf der product_idSpalte in mehrere Dateien aufteilen (aufteilen) . Auf diese Weise wird die Datei der Hive-Tabelle in zwei Dateien aufgeteilt, eine mit product_id='P1'und eine mit product_id='P2'. Wenn wir nun die obige Abfrage ausführen, wird nur die product_id='P1'Datei gescannt.

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

Die Syntax zum Erstellen der Partition ist unten angegeben. Beachten Sie, dass wir die Spaltendefinition nicht product_idzusammen mit den nicht partitionierten Spalten in der folgenden Syntax verwenden sollten. Dies sollte nur in der partitioned byKlausel sein.

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

Nachteile : Wir sollten beim Partitionieren sehr vorsichtig sein. Das heißt, es sollte nicht für Spalten verwendet werden, in denen die Anzahl der sich wiederholenden Werte sehr gering ist (insbesondere für Primärschlüsselspalten), da dies die Anzahl der partitionierten Dateien und den Overhead für die erhöht Name node.



BUCKETING
------------------
Bucketing wird verwendet, um das zu überwinden cons, was ich im Partitionierungsabschnitt erwähnt habe. Dies sollte verwendet werden, wenn eine Spalte nur sehr wenige sich wiederholende Werte enthält (Beispiel - Primärschlüsselspalte). Dies ähnelt dem Konzept des Index für die Primärschlüsselspalte im RDBMS. In unserer Tabelle können wir eine Sales_IdSpalte zum Bucketing verwenden. Dies ist nützlich, wenn wir die sales_idSpalte abfragen müssen .

Unten finden Sie die Syntax für das 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

Hier werden wir die Daten weiter in einige weitere Dateien auf Partitionen aufteilen.

Geben Sie hier die Bildbeschreibung ein

Da wir 3Buckets angegeben haben , wird es für jede in 3 Dateien aufgeteilt product_id. Es wird intern verwendet modulo operator, um zu bestimmen, in welchem ​​Eimer jeder sales_idgelagert werden soll. Zum Beispiel für die product_id='P1', die sales_id=1in gespeichert werden 000001_0 Datei (dh 1% 3 = 1), sales_id=2wird in gespeichert werden 000002_0 Datei (dh 2% 3 = 2), sales_id=3wird in gespeichert werden 000000_0 Datei (dh 3% 3 = 0) usw.

Sarath Avanavu
quelle
Wird bei numerisch gruppierten Spalten immer nur Mod nach der Anzahl der Buckets benötigt? Verwendet es für Cluster-Spalten mit hashCode()Zeichenfolgenwert das Java der Zeichenfolge als Hash-Funktion? Kann der Programmierer die Hash-Funktion auswählen?
Don Smith
Anscheinend (und gemäß meinen Experimenten) verwendet hive eine Variation der Java-Methode hashCode (): github.com/apache/hive/blob/release-1.1.0/serde/src/java/org/… . Dies wurde hier erwähnt: stackoverflow.com/questions/30594038/… .
Don Smith
3

Der Unterschied besteht darin, dass beim Bucketing die Dateien durch den Spaltennamen geteilt werden und beim Partitionieren die Dateien unter Durch einen bestimmten Wert in der Tabelle geteilt werden

Hoffentlich habe ich es richtig definiert

Uriya Harel
quelle
0

Hier gibt es tolle Antworten. Ich möchte mich kurz fassen, um den Unterschied zwischen Partition und Buckets auswendig zu lernen.

Sie partitionieren im Allgemeinen in einer weniger eindeutigen Spalte. Und Bucketing auf der einzigartigsten Säule.

Beispiel, wenn Sie die Weltbevölkerung mit Land, Personennamen und ihrer biometrischen ID als Beispiel betrachten. Wie Sie sich vorstellen können, ist das Länderfeld die weniger eindeutige Spalte und die biometrische ID die eindeutigste Spalte. Idealerweise müssten Sie die Tabelle nach Land aufteilen und nach biometrischer ID aufteilen.

SVK
quelle
-1

Die Verwendung von Partitionen in der Hive-Tabelle wird aus folgenden Gründen dringend empfohlen:

  • Das Einfügen in die Hive-Tabelle sollte schneller erfolgen (da mehrere Threads zum Schreiben von Daten in Partitionen verwendet werden).
  • Die Abfrage aus der Hive-Tabelle sollte bei geringer Latenz effizient sein.

Beispiel: -

Angenommen, die Eingabedatei (100 GB) wird in die temporäre Tabelle geladen und enthält Bankdaten aus verschiedenen Regionen.

Bienenstock Tisch ohne 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

Das Problem bei diesem Ansatz ist: Es werden ganze Daten nach Abfragen durchsucht, die Sie in dieser Tabelle ausführen. Die Reaktionszeit ist im Vergleich zu anderen Ansätzen, bei denen Partitionierung und Bucketing verwendet werden, hoch.

Bienenstock Tisch mit 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)

Vorteile - Hier kann man schneller auf Daten zugreifen, wenn Daten für bestimmte geografische Transaktionen abgefragt werden. Nachteile - Das Einfügen / Abfragen von Daten kann weiter verbessert werden, indem Daten innerhalb jeder Partition aufgeteilt werden. Siehe Bucketing-Option unten.

Bienenstock Tisch mit Partition und Bucketing

Hinweis: Erstellen Sie eine Hive-Tabelle ..... mit "CLUSTERED BY (Partiton_Column) in 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)

Vorteile - Schnelleres Einfügen. Schnellere Abfrage.

Nachteile - Durch Bucketing werden mehr Dateien erstellt. In bestimmten Fällen kann es zu Problemen mit vielen kleinen Dateien kommen

Hoffe das wird helfen !!

Ajay Ahuja
quelle