HBase
 sql >> Database >  >> NoSQL >> HBase

Utilizzo di Hive per interagire con HBase, parte 1

Questo post sul blog è stato pubblicato su Hortonworks.com prima della fusione con Cloudera. Alcuni collegamenti, risorse o riferimenti potrebbero non essere più accurati.

Questo è il primo di due post che esaminano l'uso di Hive per l'interazione con le tabelle HBase. Il secondo post è qui.

Una delle cose che mi viene chiesto di frequente è come utilizzare HBase da Apache Hive. Non solo come farlo, ma cosa funziona, come funziona e come sfruttarlo al meglio. Ho fatto un po' di ricerche in quest'area, quindi spero che questo possa essere utile a qualcuno oltre a me. Questo è un argomento che non siamo riusciti a trattare in HBase in Action, forse queste note diventeranno la base per la 2a edizione 😉 Queste note sono applicabili a Hive 0.11.x utilizzato insieme a HBase 0.94.x. Dovrebbero essere ampiamente applicabili a 0.12.x + 0.96.x, anche se non ho ancora testato tutto.

Il progetto hive include una libreria opzionale per l'interazione con HBase. È qui che viene implementato il livello ponte tra i due sistemi. L'interfaccia principale che utilizzi quando accedi a HBase dalle query di Hive è chiamata  BaseStorageHandler . Puoi anche interagire con le tabelle HBase direttamente tramite i formati Input e Output, ma il gestore è più semplice e funziona per la maggior parte degli usi.

Tabelle HBase da Hive

Usa HBaseStorageHandler per registrare le tabelle HBase con il metastore Hive. Puoi facoltativamente specificare la tabella HBase come EXTERNAL , nel qual caso Hive non creerà l'eliminazione diretta di quella tabella:per farlo dovrai utilizzare la shell HBase.

[sql]
CREATE [EXTERNAL] TABLE foo(…)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES ('hbase.table.name' =' bar');
[/sql]

L'istruzione precedente registra la tabella HBase denominata bar nel metastore di Hive, accessibile da Hive con il nome foo .

Sotto il cofano, HBaseStorageHandler sta delegando l'interazione con la tabella HBase a
HiveHBaseTableInputFormatHiveHBaseTableOutputFormat . Puoi registrare la tua tabella HBase in Hive utilizzando quelle classi direttamente, se lo desideri. L'affermazione di cui sopra è più o meno equivalente a:

[sql]
CREATE TABLE foo(…)
MEMORIZZATO COME
INPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHBaseTableInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive .hbase.HiveHBaseTableOutputFormat'
TBLPROPERTIES ('hbase.table.name' ='bar');
[/sql]

Viene fornito anche il HiveHFileOutputFormat il che significa che dovrebbe essere possibile generare file H per il caricamento in blocco anche da Hive. In pratica, non sono riuscito a farlo funzionare end-to-end (vedi HIVE-4627).

Mappatura dello schema

La registrazione della tabella è solo il primo passo. Come parte di tale registrazione, devi anche specificare una mappatura delle colonne. In questo modo colleghi i nomi delle colonne Hive alla chiave di riga e alle colonne della tabella HBase. Fallo utilizzando hbase.columns.mapping Proprietà SerDe.

[sql]
CREATE TABLE foo(rowkey STRING, a STRING, b STRING)
MEMORIZZATO DA 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
CON SERDEPROPERTIES ('hbase.columns .mapping' =':key,f:c1,f:c2')
TBLPROPERTIES ('hbase.table.name' ='bar');

[/sql]

I valori forniti nella proprietà di mappatura corrispondono uno per uno ai nomi delle colonne della tabella hive. I nomi delle colonne HBase sono completamente qualificati in base alla famiglia di colonne e utilizzi il token speciale :key per rappresentare la chiave di riga. Quanto sopra

esempio crea righe dalla tabella HBase bar disponibile tramite la tabella Hive foo . Il foo colonna rowkey esegue il mapping alla chiave di riga della tabella della HBase, ac1 nel f famiglia di colonne e b a c2 , anche nel f famiglia.

Puoi anche associare la MAP di Hive strutture dati alle famiglie di colonne HBase. In questo caso, solo il STRING Viene utilizzato il tipo alveare. L'altro tipo di Hive attualmente supportato è BINARY . Vedi la pagina wiki per altri esempi.

Interazione con i dati

Con le mappature delle colonne definite, ora puoi accedere ai dati HBase proprio come faresti con qualsiasi altro dato Hive. Al momento sono supportati solo i predicati di query semplici.

[sql]
SELEZIONARE * DA foo DOVE …;
[/sql]

Puoi anche popolare e tabella HBase usando Hive. Funziona con entrambi INTO e OVERWRITE clausole.

[sql]
DA source_hive_table INSERT INTO TABLE my_hbase_table
SELECT source_hive_table.* DOVE …;
[/sql]

Tieni presente che è presente una regressione in Hive 0.12.0 che interrompe questa funzionalità, vedi HIVE-5515.

In pratica

C'è ancora un po' di raffinatezza richiesta per avere tutto cablato correttamente in fase di esecuzione. Il modulo di interazione HBase è completamente facoltativo, quindi devi assicurarti che e le sue dipendenze HBase siano disponibili nel percorso di classe di Hive.

[bash]
$ export HADOOP_CLASSPATH=…
$ hive -e “CREATE TABLE … STORED BY ‘org.apache…HBaseStorageHandler'”
[/bash]

L'ambiente di installazione potrebbe svolgere un lavoro migliore nel gestire questo problema per gli utenti, ma per il momento devi gestirlo tu stesso. Idealmente l'hive bin script può rilevare la presenza di HBase e creare automaticamente il necessario CLASSPATH aggiustamenti. Questo miglioramento sembra essere tracciato in HIVE-2055. L'ultimo miglio è fornito dalla distribuzione stessa, assicurando che le variabili di ambiente siano impostate per hive . Questa funzionalità è fornita da BIGTOP-955.

Devi anche assicurarti che i jar necessari vengano spediti ai processi MapReduce quando esegui le tue istruzioni Hive. Hive fornisce un meccanismo per la spedizione di ulteriori dipendenze del lavoro tramite la funzione auxjars.

[bash]
$ export HIVE_AUX_JARS_PATH=…
$ hive -e “SELECT * FROM …”
[/bash]

Ho scoperto un piccolo bug nelle build HDP-1.3 che maschera i valori specificati dall'utente di HIVE_AUX_JARS_PATH . Con i diritti amministrativi, questo problema può essere risolto facilmente correggendo la riga in hive-env.sh rispettare un valore esistente. La
soluzione alternativa negli script utente consiste nell'utilizzare il SET dichiarazione per fornire un valore dopo aver lanciato l'interfaccia a riga di comando di Hive.

[bash]
SET hive.aux.jars.path =…
[/bash]

Hive dovrebbe essere in grado di rilevare quali vasetti sono necessari e aggiungerli autonomamente. HBase fornisce  TableMapReduceUtils#addDependencyJars  metodi per questo scopo. Sembra che ciò avvenga in hive-0.12.0, almeno secondo HIVE-2379.

Lavori futuri

Molto è stato detto sul supporto adeguato per il pushdown dei predicati (HIVE-1643, HIVE-2854, HIVE-3617,
HIVE-3684) e la consapevolezza del tipo di dati (HIVE-1245, HIVE-2599). Questi vanno di pari passo poiché la semantica dei predicati è definita in termini di tipi su cui operano. Si potrebbe fare di più per mappare i tipi di dati complessi di Hive come Maps e Structs anche su famiglie di colonne HBase (HIVE-3211). Il supporto per i timestamp HBase è un po' un pasticcio; non sono disponibili per le applicazioni Hive con alcun livello di granularità (HIVE-2828, HIVE-2306). L'unica interazione che un utente ha è tramite l'impostazione del gestore di archiviazione per la scrittura di un timestamp personalizzato con tutte le operazioni.

Dal punto di vista delle prestazioni, ci sono cose che Hive può fare oggi (ovvero, non dipendenti dai tipi di dati) per sfruttare HBase. C'è anche la possibilità di un hive compatibile con HBase di utilizzare le tabelle HBase come posizione di archiviazione intermedia (HIVE-3565), facilitando i join lato mappa con le tabelle delle dimensioni caricate in HBase. Hive potrebbe utilizzare la struttura indicizzata naturale di HBase (HIVE-3634, HIVE-3727), salvando potenzialmente enormi scansioni. Attualmente, l'utente non ha (nessun?) il controllo sulle scansioni eseguite. È necessario abilitare la configurazione per processo o almeno per tabella (HIVE-1233). Ciò consentirebbe a un utente esperto di HBase di fornire a Hive suggerimenti su come dovrebbe interagire con HBase. Il supporto per il campionamento diviso semplice delle tabelle HBase (HIVE-3399) potrebbe essere eseguito facilmente anche perché HBase gestisce già le partizioni delle tabelle.

Altri canali di accesso

Tutto ciò che è stato discusso finora ha richiesto a Hive di interagire con HBase RegionServer online. Le applicazioni possono ottenere un throughput significativo e godere di maggiore flessibilità interagendo direttamente con i dati HBase persistenti su HDFS. Ciò ha anche il vantaggio di impedire ai carichi di lavoro Hive di interferire con le applicazioni HBase associate a SLA online (almeno fino a quando non vedremo miglioramenti di HBase nell'isolamento QOS tra le attività, HBASE-4441).

Come accennato in precedenza, esiste il HiveHFileOutputFormat . La risoluzione di HIVE-4627 dovrebbe rendere Hive un modo semplice per generare HFile per il caricamento in blocco. Dopo aver creato gli HFiles utilizzando Hive, c'è ancora l'ultimo passaggio per eseguire
LoadIncrementalHFiles utility per copiarli e registrarli nelle regioni. Per questo, il HiveStorageHandler  l'interfaccia avrà bisogno di una sorta di hook per influenzare il piano di query mentre viene creato, consentendogli di aggiungere passaggi. Una volta in posizione, dovrebbe essere possibile SET un flag di runtime, cambiando un INSERT  operazione per utilizzare il caricamento in blocco.

HBase ha recentemente introdotto la funzione di snapshot della tabella. Ciò consente a un utente di creare una vista point-in-time persistente di una tabella, persistente su HDFS. HBase è in grado di ripristinare una tabella da uno snapshot a uno stato precedente e di creare una tabella completamente nuova da uno snapshot esistente. Hive non supporta attualmente la lettura da uno snapshot HBase. Del resto, HBase non supporta ancora i lavori MapReduce su snapshot, sebbene la funzione sia in corso di elaborazione (HBASE-8369).

Conclusioni

L'interfaccia tra HBase e Hive è giovane, ma ha un buon potenziale. Ci sono molti frutti bassi che possono essere raccolti per rendere le cose più facili e veloci. Il problema più evidente che esclude lo sviluppo di applicazioni reali è la discrepanza di impedenza tra lo schema denso tipizzato di Hive e lo schema sparso non tipizzato di HBase. Questo è tanto un problema cognitivo quanto un problema tecnico. Le soluzioni qui consentirebbero la caduta di una serie di miglioramenti, incluso molto in termini di miglioramenti delle prestazioni. Spero che continuare a lavorare per aggiungere tipi di dati a HBase (HBASE-8089) possa aiutare a colmare questa lacuna.

Le operazioni di base funzionano principalmente, almeno in modo rudimentale. Puoi leggere i dati e riscriverli in HBase utilizzando Hive. La configurazione dell'ambiente è un processo opaco e manuale, che probabilmente impedisce ai principianti di adottare gli strumenti. C'è anche la questione delle operazioni in blocco:il supporto per la scrittura di file H e la lettura di snapshot HBase utilizzando Hive è del tutto assente a questo punto. E, naturalmente, ci sono insetti sparsi ovunque. Il più grande miglioramento recente è il ritiro dell'interfaccia di HCatalog, che rimuove la necessaria decisione anticipata su quale interfaccia utilizzare.

Hive fornisce un'interfaccia SQL molto utilizzabile su HBase, che si integra facilmente in molti flussi di lavoro ETL esistenti. Tale interfaccia richiede la semplificazione di parte della semantica di BigTable fornita da HBase, ma il risultato sarà l'apertura di HBase a un pubblico di utenti molto più ampio. L'interoperabilità dell'alveare si complimenta molto bene con l'esperienza fornita da Phoenix. Hive ha il vantaggio di non richiedere le complessità di distribuzione attualmente richieste da quel sistema. Si spera che la definizione comune dei tipi consenta un futuro comprensivo.