Risposte:
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 employee
tabella di grandi dimensioni e spesso eseguiamo query con WHERE
clausole 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 date
come partizione di primo livello e employee_id
come partizione di secondo livello porti a troppe piccole partizioni. Invece, se eseguiamo il bucket della tabella dei dipendenti e la utilizziamo employee_id
come 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_id
sia 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.
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 .
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.
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.
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:
Contro:
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
Contro
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.
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_id
colonna. 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_id
definizione di colonna insieme alle colonne non partizionate nella sintassi seguente. Questo dovrebbe essere solo nella partitioned by
clausola.
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 cons
che 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_Id
colonna per il bucket. Sarà utile quando dovremo interrogare la sales_id
colonna.
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.
Dal momento che abbiamo specificato i 3
bucket, è suddiviso in 3 file ciascuno per ciascuno product_id
. Utilizza internamente modulo operator
per determinare in quale bucket sales_id
devono essere archiviati. Ad esempio, per il product_id='P1'
, il sales_id=1
sarà archiviato nel file 000001_0 (ovvero, 1% 3 = 1), sales_id=2
sarà archiviato nel file 000002_0 (cioè, 2% 3 = 2), sales_id=3
sarà archiviato nel file 000000_0 (cioè, 3% 3 = 0) ecc.
hashCode()
della stringa come funzione hash? Il programmatore può scegliere la funzione hash?
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
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.
L'uso delle partizioni nella tabella Hive è altamente raccomandato per il seguente motivo:
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 !!