Det här blogginlägget publicerades på Hortonworks.com före sammanslagningen med Cloudera. Vissa länkar, resurser eller referenser kanske inte längre är korrekta.
Detta är det första av två inlägg som undersöker användningen av Hive för interaktion med HBase-tabeller. Det andra inlägget är här.
En av de saker jag ofta får frågan om är hur man använder HBase från Apache Hive. Inte bara hur man gör det, utan vad som fungerar, hur bra det fungerar och hur man använder det på bästa sätt. Jag har forskat lite på det här området, så förhoppningsvis kommer detta att vara användbart för någon annan än mig själv. Det här är ett ämne som vi inte fick ta upp i HBase in Action, kanske kommer dessa anteckningar att bli grunden för den andra utgåvan 😉 Dessa anteckningar är tillämpliga på Hive 0.11.x som används tillsammans med HBase 0.94.x. De bör till stor del vara tillämpliga på 0.12.x + 0.96.x, även om jag inte har testat allt ännu.
Hive-projektet inkluderar ett valfritt bibliotek för interaktion med HBase. Det är här bryggskiktet mellan de två systemen implementeras. Det primära gränssnittet du använder när du kommer åt HBase från Hive-frågor kallas BaseStorageHandler
. Du kan också interagera med HBase-tabeller direkt via inmatnings- och utdataformat, men hanteraren är enklare och fungerar för de flesta användningsområden.
HBase-tabeller från Hive
Använd HBaseStorageHandler
för att registrera HBase-tabeller med Hive-metastore. Du kan valfritt ange HBase-tabellen som EXTERNAL
, i vilket fall Hive inte skapar för att ta bort den tabellen direkt – du måste använda HBase-skalet för att göra det.
[sql]
SKAPA [EXTERN] TABELL foo(…)
LAGRAD AV 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES ('hbase.table.name' =' bar');
[/sql]
Ovanstående uttalande registrerar HBase-tabellen med namnet bar
i Hive metastore, tillgänglig från Hive med namnet foo
.
Under huven, HBaseStorageHandler
delegerar interaktion med HBase-tabellen tillHiveHBaseTableInputFormat
och HiveHBaseTableOutputFormat
. Du kan registrera din HBase-tabell i Hive med hjälp av dessa klasser direkt om du vill. Ovanstående uttalande motsvarar ungefär:
[sql]
SKAPA TABELL foo(…)
LAGRAD SOM
INPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHBaseTableInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive .hbase.HiveHBaseTableOutputFormat'
TBLPROPERTIES ('hbase.table.name' ='bar');
[/sql]
Det finns också HiveHFileOutputFormat
vilket betyder att det borde vara möjligt att generera HFiles för bulkladdning från Hive också. I praktiken har jag inte fått det här att fungera från början (se HIVE-4627).
Schemamappning
Att registrera bordet är bara det första steget. Som en del av registreringen måste du också ange en kolumnmappning. Så här länkar du Hive-kolumnnamn till HBase-tabellens radknapp och kolumner. Gör det med hjälp av hbase.columns.mapping
SerDe-egenskapen.
[sql]
SKAPA TABELL foo(radtangent STRING, a STRING, b STRING)
LAGRAD AV 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
Med SERDEPROPERTIES ('hbase.columns .mapping' =':nyckel,f:c1,f:c2')
TBLPROPERTIES ('hbase.table.name' ='bar');
…
[/sql]
Värdena som anges i mappningsegenskapen motsvarar en för en kolumnnamn i hivetabellen. HBase kolumnnamn är helt kvalificerade efter kolumnfamilj, och du använder den speciella token :key
för att representera radknappen. Ovanstående
exempel gör rader från HBase-tabellen bar
tillgängligt via Hive-tabellen foo
. foo
kolumn rowkey
mappar till HBases tabells radknapp, a
till c1
i f
kolumnfamilj och b
till c2
, även i f
familj.
Du kan också koppla Hives MAP
datastrukturer till HBase kolumnfamiljer. I det här fallet, endast STRING
Bikupatyp används. Den andra Hive-typen som stöds för närvarande är BINARY
. Se wikisidan för fler exempel.
Interagera med data
Med kolumnmappningarna definierade kan du nu komma åt HBase-data precis som du skulle göra med andra Hive-data. Endast enkla frågepredikat stöds för närvarande.
[sql]
VÄLJ * FROM foo WHERE …;
[/sql]
Du kan också fylla i och HBase-tabellen med hjälp av Hive. Detta fungerar med både INTO
och OVERWRITE
klausuler.
[sql]
FRÅN source_hive_table INFOGA I TABELL my_hbase_table
VÄLJ source_hive_table.* WHERE …;
[/sql]
Observera att det finns en regression i Hive 0.12.0 som bryter den här funktionen, se HIVE-5515.
I praktiken
Det krävs fortfarande lite finess för att få allt korrekt kopplat under körning. HBase-interaktionsmodulen är helt valfri, så du måste se till att den och dess HBase-beroenden är tillgängliga på Hives klassväg.
[bash]
$ export HADOOP_CLASSPATH=…
$ hive -e “SKAPA TABELL … LAGRAD AV ‘org.apache…HBaseStorageHandler’”
[/bash]
Installationsmiljön skulle kunna göra ett bättre jobb med att hantera detta för användarna, men för närvarande måste du hantera det själv. Helst hive
bin script kan upptäcka närvaron av HBase och automatiskt skapa den nödvändiga CLASSPATH
justeringar. Denna förbättring verkar spåras i HIVE-2055. Den sista milen tillhandahålls av distributionen själv, som säkerställer att miljövariablerna är inställda för hive
. Den här funktionen tillhandahålls av BIGTOP-955.
Du måste också se till att de nödvändiga burkarna skickas ut till MapReduce-jobben när du kör dina Hive-satser. Hive tillhandahåller en mekanism för att skicka ytterligare jobbberoende via auxjars-funktionen.
[bash]
$ export HIVE_AUX_JARS_PATH=…
$ hive -e “SELECT * FROM …”
[/bash]
Jag upptäckte en liten bugg i HDP-1.3-byggen som maskerar användarspecificerade värden för HIVE_AUX_JARS_PATH
. Med administrativa rättigheter åtgärdas detta enkelt genom att korrigera raden i hive-env.sh
att respektera ett befintligt värde.
lösningen i användarskript är att använda SET
för att ange ett värde när du har lanserat Hive CLI.
[bash]
SET hive.aux.jars.path =…
[/bash]
Hive ska kunna upptäcka vilka burkar som behövs och lägga till dem själv. HBase tillhandahåller TableMapReduceUtils#addDependencyJars
metoder för detta ändamål. Det verkar som om detta görs i hive-0.12.0, åtminstone enligt HIVE-2379.
Framtida arbete
Mycket har sagts om korrekt stöd för predikat pushdown (HIVE-1643, HIVE-2854, HIVE-3617,
HIVE-3684) och datatypsmedvetenhet (HIVE-1245, HIVE-2599). Dessa går hand i hand eftersom predikatsemantik definieras i termer av de typer som de verkar på. Mer skulle kunna göras för att kartlägga Hives komplexa datatyper som Maps och Structs även till HBase-kolumnfamiljer (HIVE-3211). Stöd för HBase tidsstämplar är lite av en röra. de görs inte tillgängliga för Hive-appar med någon grad av granularitet (HIVE-2828, HIVE-2306). Den enda interaktion en användare har är via lagringshanterarens inställning för att skriva en anpassad tidsstämpel med alla operationer.
Ur ett prestandaperspektiv finns det saker som Hive kan göra idag (dvs. inte beroende på datatyper) för att dra fördel av HBase. Det finns också möjligheten för en HBase-medveten Hive att använda HBase-tabeller som mellanliggande lagringsplats (HIVE-3565), vilket underlättar kopplingar på kartsidan mot dimensionstabeller som laddas in i HBase. Hive skulle kunna använda HBases naturliga indexerade struktur (HIVE-3634, HIVE-3727), vilket potentiellt sparar enorma skanningar. För närvarande har användaren inte (någon?) kontroll över de skanningar som utförs. Konfiguration per jobb eller åtminstone per tabell bör vara aktiverad (HIVE-1233). Det skulle göra det möjligt för en HBase-kunnig användare att ge Hive tips om hur den ska interagera med HBase. Stöd för enkel delad sampling av HBase-tabeller (HIVE-3399) kan också enkelt göras eftersom HBase redan hanterar tabellpartitioner.
Andra åtkomstkanaler
Allt som diskuterats hittills har krävt att Hive interagerar med HBase RegionServers online. Appar kan komma att få betydande genomströmning och åtnjuta större flexibilitet genom att interagera direkt med HBase-data som finns kvar till HDFS. Detta har också fördelen av att förhindra Hive-arbetsbelastningar från att störa online SLA-bundna HBase-applikationer (åtminstone tills vi ser HBase-förbättringar i QOS-isolering mellan uppgifter, HBASE-4441).
Som nämnts tidigare finns det HiveHFileOutputFormat
. Att lösa HIVE-4627 borde göra Hive till ett enkelt sätt att generera HF-filer för bulkladdning. När du har skapat hFiles med hjälp av Hive, finns det fortfarande det sista steget att köraLoadIncrementalHFiles
verktyg för att kopiera och registrera dem i regionerna. För detta, HiveStorageHandler
gränssnittet kommer att behöva någon form av krok för att påverka frågeplanen när den skapas, så att den kan lägga till steg. När det väl är på plats bör det vara möjligt att SET
en körtidsflagga, byter en INSERT
operation för att använda bulklast.
HBase introducerade nyligen funktionen för ögonblicksbilder för bordet. Detta gör att en användare kan skapa en beständig punkt-i-tidsvy av en tabell, bevarad till HDFS. HBase kan återställa en tabell från en ögonblicksbild till ett tidigare tillstånd och skapa en helt ny tabell från en befintlig ögonblicksbild. Hive stöder för närvarande inte läsning från en HBase-ögonblicksbild. För den delen har HBase ännu inte stöd för MapReduce-jobb över ögonblicksbilder, även om funktionen är ett pågående arbete (HBASE-8369).
Slutsatser
Gränssnittet mellan HBase och Hive är ungt, men har fin potential. Det finns mycket lågt hängande frukt som kan plockas upp för att göra saker enklare och snabbare. Det mest iögonfallande problemet som hindrar verklig applikationsutveckling är impedansmissanpassningen mellan Hives skrivna, täta schema och HBases otypade, glesa schema. Detta är lika mycket ett kognitivt problem som ett tekniskt problem. Lösningar här skulle tillåta ett antal förbättringar att falla ut, inklusive mycket i form av prestandaförbättringar. Jag hoppas att fortsatt arbete med att lägga till datatyper till HBase (HBASE-8089) kan hjälpa till att överbrygga detta gap.
Grundläggande operationer fungerar för det mesta, åtminstone på ett rudimentärt sätt. Du kan läsa data ur och skriva tillbaka data till HBase med Hive. Att konfigurera miljön är en ogenomskinlig och manuell process, en process som sannolikt hindrar nybörjare från att använda verktygen. Det finns också frågan om bulkoperationer – stöd för att skriva HF-filer och läsa HBase-ögonblicksbilder med Hive saknas helt för närvarande. Och naturligtvis finns det buggar utströdda överallt. Den största förbättringen på senare tid är utfasningen av HCatalogs gränssnitt, vilket tar bort det nödvändiga beslutet i förväg om vilket gränssnitt som ska användas.
Hive tillhandahåller ett mycket användbart SQL-gränssnitt ovanpå HBase, ett som enkelt integreras i många befintliga ETL-arbetsflöden. Det gränssnittet kräver att en del av BigTable-semantiken som HBase tillhandahåller förenklas, men resultatet blir att öppna upp HBase för en mycket bredare publik av användare. Hive-interopet kompletterar extremt väl upplevelsen från Phoenix. Hive har fördelen av att inte kräva den installationskomplexitet som för närvarande krävs av det systemet. Förhoppningsvis kommer den vanliga definitionen av typer att möjliggöra en gratis framtid.