Qual è la differenza tra il partizionamento e il bucket di una tabella in Hive?


129

So che entrambi vengono eseguiti su una colonna della tabella ma come è diversa ogni operazione.

Risposte:


247

I dati di partizionamento vengono spesso utilizzati per distribuire il carico in orizzontale, questo ha un vantaggio in termini di prestazioni e aiuta a organizzare i dati in modo logico. Esempio : se abbiamo a che fare con una employeetabella di grandi dimensioni e spesso eseguiamo query con WHEREclausole che limitano i risultati a un determinato paese o dipartimento. Per una risposta più rapida alla query può essere la tabella Hive PARTITIONED BY (country STRING, DEPT STRING). Le tabelle di partizionamento cambiano il modo in cui Hive struttura l'archiviazione dei dati e Hive ora creerà sottodirectory che riflettono la struttura di partizionamento come

... / dipendenti / paese = ABC / DEPT = XYZ .

Se la query limita il dipendente da country=ABC, scansionerà solo il contenuto di una directory country=ABC. Ciò può migliorare notevolmente le prestazioni delle query, ma solo se lo schema di partizionamento riflette il filtro comune. La funzione di partizionamento è molto utile in Hive, tuttavia, un progetto che crea troppe partizioni può ottimizzare alcune query, ma può essere dannoso per altre query importanti. Un altro svantaggio è che ci sono troppe partizioni è il gran numero di file e directory Hadoop creati inutilmente e sovraccarichi su NameNode poiché deve conservare tutti i metadati per il file system in memoria.

Il bucket è un'altra tecnica per decomporre i set di dati in parti più gestibili. Ad esempio, supponiamo che una tabella utilizzi datecome partizione di primo livello e employee_idcome partizione di secondo livello porti a troppe piccole partizioni. Invece, se eseguiamo il bucket della tabella dei dipendenti e la utilizziamo employee_idcome colonna di bucket, il valore di questa colonna verrà convertito in bucket da un numero definito dall'utente. I record con lo stesso employee_id verranno sempre archiviati nello stesso bucket. Supponendo che il numero di employee_idsia molto maggiore del numero di bucket, ogni bucket ne avrà molti employee_id. Durante la creazione della tabella è possibile specificare likeCLUSTERED BY (employee_id) INTO XX BUCKETS;dove XX è il numero di bucket. La benna presenta numerosi vantaggi. Il numero di bucket è fisso in modo che non fluttui con i dati. Se due tabelle sono raggruppate employee_id, Hive può creare un campionamento logicamente corretto. Il bucket aiuta anche a creare efficienti join a lato della mappa, ecc.


4
Grazie Navneet. Tuttavia, puoi elaborare come avviene il bucket con il partizionamento? Supponiamo che se specificiamo 32 bucket nella clausola CLUSED BY e l'istruzione CREATE TABLE contenga anche la clausola Partitioning, come verranno gestite insieme partizioni e bucket? Il numero di partizioni sarà limitato a 32? O per ogni partizione, verranno creati 32 bucket? Ogni bucket è un file HDFS?
sgsi,

12
Una tabella hive può avere sia il partizionamento che il bucket. Sulla base della clausola di partizione, per ogni partizione verranno creati 32 bucket. Sì file HDFS.
Navneet Kumar,

7
@sgsi Partition è una cartella, bucket è un file.
leftjoin

12
Per la cronaca, questa risposta deriva dal testo di Programming Hive (O'Reilly, 2012).
ianmcook,

1
Ho trovato utile questo link. Ha informazioni che aggiungeranno più valore a questa risposta. linkedin.com/pulse/…
Alex Raj Kaliamoorthy,

129

Mancano alcuni dettagli nelle spiegazioni precedenti. Per comprendere meglio il funzionamento del partizionamento e del bucket, è necessario esaminare il modo in cui i dati vengono archiviati in hive. Diciamo che hai un tavolo

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

quindi hive memorizzerà i dati in una gerarchia di directory come

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

Quindi, devi stare attento durante il partizionamento, perché se, ad esempio, partizioni per employee_id e hai milioni di dipendenti, finirai per avere milioni di directory nel tuo file system. Il termine " cardinalità " si riferisce al numero di possibili valori che un campo può avere. Ad esempio, se si dispone di un campo "Paese", i paesi nel mondo sono circa 300, quindi la cardinalità sarebbe ~ 300. Per un campo come "timestamp_ms", che cambia ogni millisecondo, la cardinalità può essere miliardi. In generale, quando si sceglie un campo per il partizionamento, non dovrebbe avere una cardinalità elevata, perché finirai con troppe directory nel tuo file system.

D'altra parte, il clustering noto come bucketing avrà come risultato un numero fisso di file, poiché si specifica il numero di bucket. Quello che farà l'alveare è di prendere il campo, calcolare un hash e assegnare un record a quel bucket. Ma cosa succede se usi diciamo 256 secchi e il campo su cui stai lavorando ha una cardinalità bassa (ad esempio, è uno stato degli Stati Uniti, quindi possono essere solo 50 valori diversi)? Avrai 50 secchi con dati e 206 secchi senza dati.

Qualcuno ha già menzionato come le partizioni possono ridurre drasticamente la quantità di dati che stai interrogando. Quindi, nella mia tabella di esempio, se vuoi eseguire una query solo da una certa data in avanti, il partizionamento per anno / mese / giorno ridurrà drasticamente la quantità di IO. Penso che qualcuno abbia anche menzionato il modo in cui il bucketing può velocizzare i join con altri tavoli che hanno esattamente lo stesso bucket , quindi nel mio esempio, se si uniscono due tavoli sullo stesso employee_id, l'hive può eseguire il bucket bucket per bucket (anche meglio se sono già ordinati per employee_id poiché raccoglierà parti già ordinate, che funziona in tempo lineare aka O (n)).

Quindi, il bucket funziona bene quando il campo ha una cardinalità elevata e i dati sono distribuiti uniformemente tra i bucket. Il partizionamento funziona meglio quando la cardinalità del campo di partizionamento non è troppo elevata.

Inoltre, puoi partizionare su più campi , con un ordine (anno / mese / giorno è un buon esempio), mentre puoi eseguire il bucket su un solo campo .


Potete per favore spiegare il comportamento CLUSTERED-BY con SORTED-BY in un esempio? Come nel mio esempio, ho trovato SORTED-BY che non faceva nulla. Mi manca qualcosa.
Jagadish Talluri,

2
CLUSTER PER x, y è come scrivere DISTRIBUIRE PER x, y ORDINARE PER x, y (vedere cwiki.apache.org/confluence/display/Hive/… ) quindi aggiungere SORT BY a CLUSTERED BY non ha alcun effetto.
Roberto Congiu,

Interessante, sono d'accordo sull'uso nella query selezionata. Ma mi chiedevo perché le persone stiano usando raggruppate e ordinate insieme nell'istruzione di creazione della tabella. Se non c'è alcun significato per SORTED BY in DDL, perché questa parola chiave è presente? Non l'ho capito.
Jagadish Talluri,

SORTED BY è pensato per essere usato con DISTRIBUTED BY. Ad esempio, potresti voler distribuire per ID utente e ordinare in base al tempo all'interno del bucket. CLUSTER BY è solo una scorciatoia per quando la clausola SORTED BY e DISTRIBUTED BY sono uguali. L'unica cosa a cui riesco a pensare è se stai distribuendo per x, y e ordinando per x, yey
Roberto Congiu

Non sono sicuro di cosa intendi con "puoi fare un secchio su un solo campo". Penso che sia possibile eseguire il bucket in più campi. La funzione di hashing prenderà semplicemente tutti i campi e li combinerà.
Istvan

18

Penso di essere in ritardo nel rispondere a questa domanda, ma continua a presentarsi nei miei feed.

Navneet ha fornito un'ottima risposta. Aggiungendolo visivamente.

Il partizionamento aiuta nell'eliminazione dei dati, se utilizzato nella clausola WHERE, dove l'ottimizzazione aiuta a organizzare i dati in ciascuna partizione in più file, così come lo stesso set di dati viene sempre scritto nello stesso bucket. Aiuta molto a unire le colonne.

Supponiamo di avere una tabella con cinque colonne, nome, server_date, some_col3, some_col4 e some_col5. Supponiamo che tu abbia partizionato la tabella su server_date e diviso sulla colonna del nome in 10 bucket, la struttura del tuo file sarà simile al seguente.

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

Qui server_date = xyz è la partizione e 000 file sono i bucket in ciascuna partizione. I bucket vengono calcolati in base ad alcune funzioni hash, quindi le righe con nome = Sandy andranno sempre nello stesso bucket.


2
Secondo Roberto in precedenza, la risposta server_data sarebbe un cattivo esempio di partizionamento in quanto il suo valore di cardinalità è davvero alto. E così finirai per avere troppe cartelle in hdfs.
Gaurang Shah,

server_date è menzionato come esempio qui. Nel mondo reale, la partizione avviene generalmente come rappresentato da Roberto, rompendo la data in anno / mese / giorno. Ecco come dovrebbe essere.
Priyesh,

17

Partizionamento dell'alveare:

La partizione divide una grande quantità di dati in più sezioni in base al valore delle colonne di una tabella.

Supponiamo che tu stia memorizzando informazioni di persone in tutto il mondo sparse in oltre 196 paesi che coprono circa 500 milioni di voci. Se vuoi interrogare persone di un determinato paese (Città del Vaticano), in assenza di partizionamento, devi scansionare tutte le 500 parti di voci anche per recuperare migliaia di voci di un paese. Se si partiziona la tabella in base al paese, è possibile ottimizzare il processo di interrogazione semplicemente controllando i dati per una sola partizione di paese. La partizione hive crea una directory separata per un valore di colonna.

Professionisti:

  1. Distribuire il carico di esecuzione in senso orizzontale
  2. Esecuzione più rapida di query in caso di partizione con basso volume di dati. ad esempio, ottenere la popolazione da " Città del Vaticano " ritorna molto velocemente invece di cercare l'intera popolazione del mondo.

Contro:

  1. Possibilità di troppe piccole creazioni di partizioni - troppe directory.
  2. Efficace per i dati a basso volume per una determinata partizione. Ma alcune query come raggruppare per volume elevato di dati richiedono ancora molto tempo per essere eseguite. ad esempio, il raggruppamento della popolazione della Cina richiederà molto tempo rispetto al raggruppamento della popolazione nella Città del Vaticano. La partizione non risolve il problema della reattività in caso di inclinazione dei dati verso un determinato valore di partizione.

Alveare Bucketing:

Il bucket decompone i dati in parti più gestibili o uguali.

Con il partizionamento è possibile creare più piccole partizioni in base ai valori di colonna. Se vai per il bucket, stai limitando il numero di bucket per archiviare i dati. Questo numero è definito durante gli script di creazione della tabella.

Professionisti

  1. A causa della parità di volumi di dati in ciascuna partizione, i join sul lato della mappa saranno più rapidi.
  2. Risposta più rapida alle query come il partizionamento

Contro

  1. È possibile definire il numero di bucket durante la creazione della tabella ma i programmatori devono caricare manualmente un volume uguale di dati.

9

Prima di entrare Bucketing, dobbiamo capire cos'è Partitioning. Prendiamo la tabella seguente come esempio. Si noti che ho fornito solo 12 record nell'esempio seguente per la comprensione a livello di principiante. In scenari in tempo reale potresti avere milioni di record.

inserisci qui la descrizione dell'immagine



Il partizionamento
---------------------
Partitioning viene utilizzato per ottenere prestazioni durante l'interrogazione dei dati. Ad esempio, nella tabella sopra, se scriviamo il sql sottostante, è necessario scansionare tutti i record nella tabella che riducono le prestazioni e aumentano le spese generali.

select * from sales_table where product_id='P1'

Per evitare la scansione completa della tabella e leggere solo i record relativi product_id='P1'possiamo partizionare (dividere i file della tabella hive) in più file in base alla product_idcolonna. In questo modo il file della tabella hive sarà diviso in due file uno con product_id='P1'e l'altro con product_id='P2'. Ora quando eseguiamo la query sopra, scansionerà solo il product_id='P1'file.

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

La sintassi per la creazione della partizione è riportata di seguito. Si noti che non dovremmo usare la product_iddefinizione di colonna insieme alle colonne non partizionate nella sintassi seguente. Questo dovrebbe essere solo nella partitioned byclausola.

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

Contro : dovremmo stare molto attenti durante il partizionamento. Cioè, non dovrebbe essere usato per le colonne in cui il numero di valori ripetitivi è molto inferiore (in particolare le colonne chiave primaria) in quanto aumenta il numero di file partizionati e aumenta il sovraccarico per Name node.



BUCKETING
------------------
Bucketing è usato per superare quello consche ho citato nella sezione di partizionamento. Questo dovrebbe essere usato quando ci sono pochissimi valori ripetuti in una colonna (esempio - colonna chiave primaria). Questo è simile al concetto di indice sulla colonna chiave primaria in RDBMS. Nella nostra tabella, possiamo prendere la Sales_Idcolonna per il bucket. Sarà utile quando dovremo interrogare la sales_idcolonna.

Di seguito è riportata la sintassi per il bucket.

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

Qui divideremo ulteriormente i dati in pochi altri file sopra le partizioni.

inserisci qui la descrizione dell'immagine

Dal momento che abbiamo specificato i 3bucket, è suddiviso in 3 file ciascuno per ciascuno product_id. Utilizza internamente modulo operatorper determinare in quale bucket sales_iddevono essere archiviati. Ad esempio, per il product_id='P1', il sales_id=1sarà archiviato nel file 000001_0 (ovvero, 1% 3 = 1), sales_id=2sarà archiviato nel file 000002_0 (cioè, 2% 3 = 2), sales_id=3sarà archiviato nel file 000000_0 (cioè, 3% 3 = 0) ecc.


Per le colonne con cluster numerici, prende sempre mod dal numero di bucket? Per le colonne in cluster con valori di stringa, utilizza Java hashCode()della stringa come funzione hash? Il programmatore può scegliere la funzione hash?
Don Smith,

Apparentemente (e per i miei esperimenti) l'hive usa una variante del metodo hashCode () di Java: github.com/apache/hive/blob/release-1.1.0/serde/src/java/org/… . Questo è stato menzionato qui: stackoverflow.com/questions/30594038/… .
Don Smith,

3

La differenza è che il bucketing divide i file per Nome colonna e il partizionamento divide i file in Per un valore particolare all'interno della tabella

Spero di averlo definito correttamente


0

Ci sono ottime risposte qui. Vorrei mantenerlo breve per memorizzare la differenza tra partizione e bucket.

In genere si esegue la partizione su una colonna meno unica. E Bucketing sulla colonna più unica.

Esempio se si considera la popolazione mondiale con il paese, il nome della persona e il loro ID bio-metrico come esempio. Come puoi immaginare, il campo Paese sarebbe la colonna meno unica e l'ID bio-metrico sarebbe la colonna più unica. Quindi, idealmente, dovresti dividere la tabella per paese e dividerla per ID bio-metrico.


-1

L'uso delle partizioni nella tabella Hive è altamente raccomandato per il seguente motivo:

  • L'inserimento nella tabella Hive dovrebbe essere più veloce (poiché utilizza più thread per scrivere dati su partizioni)
  • Le query dalla tabella Hive dovrebbero essere efficienti con bassa latenza.

Esempio :-

Supponiamo che il file di input (100 GB) sia caricato in una tabella temporanea e contenga dati bancari provenienti da diverse aree geografiche.

Tabella dell'alveare senza partizione

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

Il problema con questo approccio è: scansionerà interi dati per qualsiasi query eseguita su questa tabella. Il tempo di risposta sarà elevato rispetto ad altri approcci in cui vengono utilizzati il ​​partizionamento e il bucket.

Tavolo alveare con partizione

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)

Pro: qui è possibile accedere ai dati più rapidamente quando si tratta di interrogare i dati per specifiche transazioni geografiche. Contro: l'inserimento / l'interrogazione di dati può essere ulteriormente migliorato suddividendo i dati all'interno di ciascuna partizione. Vedi l'opzione Bucketing di seguito.

Tavolo alveare con partizione e bucket

Nota: crea una tabella hive ..... con "CLUSTERED BY (Partiton_Column) in 5 secchi

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)

Pro: inserto più veloce. Query più veloce.

Contro: Bucketing creerà più file. Potrebbero esserci problemi con molti piccoli file in alcuni casi specifici

Spero che questo possa aiutare !!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.