Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Partizioni e bucket

Per analizzare grandi moli di dati, è facile penalizzare le prestazioni. Per risolvere questo problema, Hive permette l'uso di partizioni e bucket.
Per analizzare grandi moli di dati, è facile penalizzare le prestazioni. Per risolvere questo problema, Hive permette l'uso di partizioni e bucket.
Link copiato negli appunti

Considerando che Hive deve svolgere per lo più operazioni di analisi, le grandi moli di dati da trattare possono
facilmente penalizzare le prestazioni. Sono previste però accortezze che permettono di migliorare le prestazioni: stiamo parlando di partizioni e
bucket. Partizionare una tabella significa "suggerire"
ad Hive una sua suddivisione su disco in base ad una chiave di partizionamento.
Tale chiave sarà basata sui valori di un particolare campo. L'utilizzo di bucket comporta invece una suddivisione fisica dei dati su disco in porzioni possibilmente
eque. In fase di creazione della tabella si può specificare in quanti bucket vogliamo che i dati vengano suddivisi usando le parole chiave
CLUSTERED BY (nome_campo) IN numero_bucket BUCKETS. In questa lezione tuttavia ci interessiamo per lo più alle partizioni e
dal prossimo paragrafo vediamo come applicarle.

Preparazione all'esempio

Al fine di ottenere soddisfacenti prestazioni è fondamentale scegliere il campo più adeguato in base a cui partizionare i dati
regolandosi sulle interrogazioni che si immagina di dover svolgere.

Per la nostra sperimentazione metteremo a confronto l'approccio ai dati con e senza partizioni. Useremo un file di dati
CSV (scaricabile qui)
consistente in una serie di righe che simulano gli incassi ottenuti da una catena commerciale. Ogni riga è composta da due
valori: un codice alfanumerico che indica il punto vendita in Italia che ha conseguito l'introito ed un numero che ne rappresenta il
valore.

Ad esempio, la riga:

RM001,150

indica una vendita di 150 euro verificatasi presso il punto vendita RM001. I codici del punto vendita avranno tutti un formato
simile e supporremo che i primi due caratteri rappresentino la provincia di collocazione.

Applicazione di partizioni

Supponiamo di voler caricare il file incassi.csv in una tabella Hive, in un'installazione basata su HDFS. Ignorando la problematica
delle partizioni potremmo definire la tabella con una struttura classica, organizzata internamente come una serie di righe formattate con
una virgola per separatore tra i singoli campi:

CREATE TABLE incassi
(codice STRING,
importo DECIMAL)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';

In questo modo, abbiamo previsto due campi, ognuno in grado di rappresentare una colonna del foglio CSV. I dati
possono essere caricati, come già visto,
nel seguente modo:

LOAD DATA LOCAL INPATH 'incassi.csv' INTO TABLE incassi;

Imponendo però la presenza di partizioni potremo sin da subito specificarne l'utilizzo all'interno
della struttura della tabella. Pensiamo una tabella di questo tipo che prende nome incassi_part:

CREATE TABLE incassi_part
(importo DECIMAL)
PARTITIONED BY(codice STRING);

Come si vede abbiamo usato i due campi in modo diverso. Il primo, importo, rappresenta davvero un valore memorizzato mentre
il secondo, codice, viene usato come identificatore della partizione. Ciò può essere utile per facilitare delle query che siano
orientate al recupero e all'elaborazione di valori provenienti dai medesimi punti vendita. In pratica, stiamo dicendo ad Hive:
disponi i dati che ti fornisco nel modo più comodo affinchè ne sia facilitato il recupero di tutto ciò che attiene allo stesso codice.

Come si vede abbiamo usato la parola chiave PARTITIONED BY seguita da una coppia di parentesi tonde in cui inseriamo il campo
che contiene i valori distintivi delle singole partizioni. Uno dei possibili modi per popolare una tabella partizionata è questo:

INSERT INTO TABLE incassi_part PARTITION(codice) SELECT importo, codice FROM incassi;

facendo attenzione che sia impostata adeguatamente la proprietà hive.exec.dynamic.partition.mode. Per appurare quest'ultima
circostanza è sufficiente eseguire (da script o da interprete interattivo) il seguente comando:

SET hive.exec.dynamic.partition.mode=nonstrict;

Questo permetterà un'attivazione dinamica delle partizioni.

Provando a verificare le due tabelle, incassi e incassi_part, attraverso la console di Hive esse potrebbero apparire assolutamente simili:

hive> SELECT COUNT(*) FROM incassi;
OK
639
hive> SELECT COUNT(*) FROM incassi_part;
OK
639

Il conteggio delle loro righe ha sortito il medesimo risultato sebbene la tabella partizionata abbia risposto in maniera più pronta.
Pertanto nell'uso pratico di una query la tabella partizionata apparirà del tutto simile ad una classica. La loro struttura
interna è comunque diversa, infatti:

hive> DESCRIBE incassi;
OK
codice                  string
importo                 decimal(10,0)
hive> DESCRIBE incassi_part;
OK
importo                 decimal(10,0)
codice                  string
# Partition Information
# col_name              data_type               comment
codice                  string

Dall'output del comando DESCRIBE si evince quale delle due tabelle è dotata di partizioni: queste sono infatti elementi
fisici appartenenti alla natura stessa della tabella che è stata creata.

Navigando la struttura fisica del database su HDFS, ci accorgiamo di come siano fisicamente diverse le due tabelle. Sempre
dall'interno della console di Hive possiamo impartire comandi HDFS anteponendo loro la parola chiave dfs e terminandoli con un
punto e virgola:

hive> dfs -ls /warehouse/analisi.db;
Found 2 items
drwxr-xr-x   ... /warehouse/analisi.db/incassi
drwxr-xr-x   ... /warehouse/analisi.db/incassi_part

Vediamo così che la cartella analisi.db su HDFS (/warehouse nella nostra configurazione è la home dei database
di Hive e analisi è il nome che abbiamo usato per il database di esempio) contiene due altre cartelle: incassi e incassi_part.
La prima delle due (relativa alla tabella non partizionata) al suo interno contiene il file:

hive> dfs -ls /warehouse/analisi.db/incassi;
Found 1 items
-rw-r--r--   .... /warehouse/analisi.db/incassi/incassi.csv

mentre la seconda (quella partizionata) contiene:

hive> dfs -ls /warehouse/analisi.db/incassi_part;
Found 5 items
drwxr-xr-x   ...    /warehouse/analisi.db/incassi_part/codice=MI001
drwxr-xr-x   ...    /warehouse/analisi.db/incassi_part/codice=NA002
drwxr-xr-x   ...    /warehouse/analisi.db/incassi_part/codice=NA003
drwxr-xr-x   ...    /warehouse/analisi.db/incassi_part/codice=RM001
drwxr-xr-x   ...    /warehouse/analisi.db/incassi_part/codice=TO002

Esattamente c'è una cartella (con relativi file all'interno) per ogni possibile valore del campo codice: questo significa partizionare
i dati. Ad esempio, la cartella codice=RM001 contiene dati in questo formato:

hive> dfs -cat /warehouse/analisi.db/incassi_part/codice=RM001/000000_0;
108
165
69
144
108
159
...

Pertanto con le partizioni, il dato relativo al codice non viene memorizzato ma serve solo per distinguere i singoli file. I dati restituiti
dal codice precedente corrispondono ai seguenti record estratti con HiveQL:

hive> SELECT * FROM incassi WHERE codice='RM001' LIMIT 6;
OK
RM001   108
RM001   165
RM001   69
RM001   144
RM001   108
RM001   159

Ti consigliamo anche