Dette blogindlæg blev offentliggjort på Hortonworks.com før fusionen med Cloudera. Nogle links, ressourcer eller referencer er muligvis ikke længere nøjagtige.
Dette er det første af to indlæg, der undersøger brugen af Hive til interaktion med HBase-tabeller. Det andet indlæg er her.
En af de ting, jeg ofte bliver spurgt om, er, hvordan man bruger HBase fra Apache Hive. Ikke kun hvordan man gør det, men hvad der virker, hvor godt det virker, og hvordan man gør god brug af det. Jeg har forsket lidt i dette område, så forhåbentlig vil dette være nyttigt for andre end mig selv. Dette er et emne, som vi ikke nåede at dække i HBase in Action, måske bliver disse noter grundlaget for 2. udgave 😉 Disse noter gælder for Hive 0.11.x brugt sammen med HBase 0.94.x. De burde stort set være anvendelige til 0.12.x + 0.96.x, selvom jeg ikke har testet alt endnu.
Hive-projektet inkluderer et valgfrit bibliotek til interaktion med HBase. Det er her, brolaget mellem de to systemer implementeres. Den primære grænseflade, du bruger, når du får adgang til HBase fra Hive-forespørgsler, kaldes BaseStorageHandler
. Du kan også interagere med HBase-tabeller direkte via input- og outputformater, men handleren er enklere og fungerer til de fleste anvendelser.
HBase-tabeller fra Hive
Brug HBaseStorageHandler
for at registrere HBase-tabeller med Hive-metastore. Du kan valgfrit angive HBase-tabellen som EXTERNAL
, i hvilket tilfælde Hive ikke opretter for at droppe den tabel direkte – du skal bruge HBase-skallen for at gøre det.
[sql]
OPRET [EKSTERN] TABEL foo(…)
LAGET AF 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES ('hbase.table.name' =' bar');
[/sql]
Ovenstående sætning registrerer HBase-tabellen med navnet bar
i Hive-metastore, tilgængelig fra Hive under navnet foo
.
Under motorhjelmen, HBaseStorageHandler
uddelegerer interaktion med HBase-tabellen tilHiveHBaseTableInputFormat
og HiveHBaseTableOutputFormat
. Du kan registrere din HBase-tabel i Hive ved at bruge disse klasser direkte, hvis du ønsker det. Ovenstående erklæring svarer nogenlunde til:
[sql]
OPRET TABEL foo(…)
LAMMET SOM
INPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHBaseTableInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive .hbase.HiveHBaseTableOutputFormat'
TBLPROPERTIES ('hbase.table.name' ='bar');
[/sql]
Der er også leveret HiveHFileOutputFormat
hvilket betyder, at det også burde være muligt at generere HFiles til bulkloading fra Hive. I praksis har jeg ikke fået dette til at fungere ende-til-ende (se HIVE-4627).
Skemakortlægning
Registrering af bordet er kun det første skridt. Som en del af denne registrering skal du også angive en kolonnetilknytning. Sådan knytter du Hive-kolonnenavne til HBase-tabellens rækketaster og kolonner. Gør det ved at bruge hbase.columns.mapping
SerDe ejendom.
[sql]
OPRET TABEL foo(rækketast STRING, a STRING, b STRING)
GEMET AF 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
MED SERDEPROPERTIES ('hbase.columns .mapping' =':key,f:c1,f:c2')
TBLPROPERTIES ('hbase.table.name' ='bar');
…
[/sql]
Værdierne, der er angivet i tilknytningsegenskaben, svarer én-til-én med kolonnenavne i hive-tabellen. HBase-kolonnenavne er fuldt kvalificerede efter kolonnefamilie, og du bruger det specielle token :key
for at repræsentere rækketasten. Ovenstående
eksempel laver rækker fra HBase-tabellen bar
tilgængelig via Hive-tabellen foo
. foo
kolonne rowkey
maps til HBase-tabellens rækketast, a
til c1
i f
kolonnefamilie og b
til c2
, også i f
familie.
Du kan også tilknytte Hives MAP
datastrukturer til HBase kolonnefamilier. I dette tilfælde er det kun STRING
Hive type bruges. Den anden Hive-type, der i øjeblikket understøttes, er BINARY
. Se wiki-siden for flere eksempler.
Interaktion med data
Med kolonnetilknytningerne defineret kan du nu få adgang til HBase-data ligesom du ville have andre Hive-data. Kun simple forespørgselsprædikater understøttes i øjeblikket.
[sql]
VÆLG * FRA foo WHERE …;
[/sql]
Du kan også udfylde og HBase-tabellen ved hjælp af Hive. Dette fungerer med både INTO
og OVERWRITE
klausuler.
[sql]
FRA source_hive_table INSERT INTO TABLE my_hbase_table
SELECT source_hive_table.* WHERE …;
[/sql]
Vær opmærksom på, at der er en regression i Hive 0.12.0, som bryder denne funktion, se HIVE-5515.
I praksis
Der kræves stadig lidt finesse for at få alt tilsluttet ordentligt under kørsel. HBase-interaktionsmodulet er helt valgfrit, så du skal sørge for, at det og dets HBase-afhængigheder er tilgængelige på Hives klassesti.
[bash]
$ eksport HADOOP_CLASSPATH=…
$ hive -e “CREATE TABLE … LAGET BY ‘org.apache…HBaseStorageHandler’”
[/bash]
Installationsmiljøet kunne gøre et bedre stykke arbejde med at håndtere dette for brugerne, men i øjeblikket skal du administrere det selv. Ideelt set hive
bin script kan registrere tilstedeværelsen af HBase og automatisk lave den nødvendige CLASSPATH
justeringer. Denne forbedring ser ud til at være sporet i HIVE-2055. Den sidste mile leveres af selve distributionen, som sikrer, at miljøvariablerne er indstillet til hive
. Denne funktionalitet leveres af BIGTOP-955.
Du skal også sørge for, at de nødvendige krukker sendes ud til MapReduce-jobbene, når du udfører dine Hive-sætninger. Hive giver en mekanisme til forsendelse af yderligere jobafhængigheder via auxjars-funktionen.
[bash]
$ eksport HIVE_AUX_JARS_PATH=…
$ hive -e “SELECT * FROM …”
[/bash]
Jeg opdagede en lille fejl i HDP-1.3 builds, som maskerer brugerspecificerede værdier for HIVE_AUX_JARS_PATH
. Med administrative rettigheder løses dette nemt ved at rette linjen i hive-env.sh
at respektere en eksisterende værdi.
løsningen i brugerscripts er at bruge SET
erklæring for at angive en værdi, når du har lanceret Hive CLI.
[bash]
SET hive.aux.jars.path =…
[/bash]
Hive skal kunne opdage, hvilke krukker der er nødvendige og selv tilføje dem. HBase leverer TableMapReduceUtils#addDependencyJars
metoder til dette formål. Det ser ud til, at dette er gjort i hive-0.12.0, i det mindste i henhold til HIVE-2379.
Fremtidigt arbejde
Der er blevet sagt meget om korrekt understøttelse af prædikat-pushdown (HIVE-1643, HIVE-2854, HIVE-3617,
HIVE-3684) og datatypebevidsthed (HIVE-1245, HIVE-2599). Disse går hånd i hånd, da prædikatsemantik er defineret i forhold til de typer, de opererer på. Der kunne også gøres mere for at kortlægge Hives komplekse datatyper som Maps og Structs til HBase-søjlefamilier (HIVE-3211). Understøttelse af HBase-tidsstempler er lidt af et rod. de er ikke gjort tilgængelige for Hive-applikationer med nogen grad af granularitet (HIVE-2828, HIVE-2306). Den eneste interaktion, en bruger har, er via lagerbehandlerindstilling til at skrive et tilpasset tidsstempel med alle handlinger.
Fra et ydeevneperspektiv er der ting, Hive kan gøre i dag (dvs. ikke afhængig af datatyper) for at drage fordel af HBase. Der er også muligheden for en HBase-bevidst Hive til at gøre brug af HBase-tabeller som mellemliggende lagringsplacering (HIVE-3565), hvilket letter kortsidesammenføjninger mod dimensionstabeller indlæst i HBase. Hive kunne gøre brug af HBases naturlige indekserede struktur (HIVE-3634, HIVE-3727), hvilket potentielt gemmer enorme scanninger. I øjeblikket har brugeren ikke (nogen?) kontrol over de scanninger, der udføres. Konfiguration pr. job eller i det mindste pr. tabel skal være aktiveret (HIVE-1233). Det ville gøre det muligt for en HBase-kyndig bruger at give Hive hints om, hvordan den skal interagere med HBase. Understøttelse af simpel opdelt sampling af HBase-tabeller (HIVE-3399) kunne også nemt udføres, fordi HBase allerede administrerer tabelpartitioner.
Andre adgangskanaler
Alt det hidtil diskuterede har krævet, at Hive interagerer med online HBase RegionServers. Applikationer kan stå til at få en betydelig gennemstrømning og nyde større fleksibilitet ved at interagere direkte med HBase-data, der vedbliver med HDFS. Dette har også den fordel, at det forhindrer Hive-arbejdsbelastninger i at forstyrre online SLA-bundne HBase-applikationer (i det mindste indtil vi ser HBase-forbedringer i QOS-isolering mellem opgaver, HBASE-4441).
Som tidligere nævnt er der HiveHFileOutputFormat
. Løsning af HIVE-4627 skulle gøre Hive til en ligetil måde at generere HF-filer til masseindlæsning. Når du har oprettet HFiles ved hjælp af Hive, er der stadig det sidste trin i at køreLoadIncrementalHFiles
værktøj til at kopiere og registrere dem i regionerne. Til dette skal HiveStorageHandler
grænsefladen skal bruge en slags hook for at påvirke forespørgselsplanen, efterhånden som den oprettes, så den kan tilføje trin. Når det er på plads, burde det være muligt at SET
et runtime-flag, der skifter en INSERT
operation for at bruge bulkload.
HBase introducerede for nylig table snapshot-funktionen. Dette giver en bruger mulighed for at oprette en vedvarende punkt-i-tidsvisning af en tabel, persisted til HDFS. HBase er i stand til at gendanne en tabel fra et øjebliksbillede til en tidligere tilstand og oprette en helt ny tabel fra et eksisterende øjebliksbillede. Hive understøtter i øjeblikket ikke læsning fra et HBase-øjebliksbillede. For den sags skyld understøtter HBase endnu ikke MapReduce-job over snapshots, selvom funktionen er et igangværende arbejde (HBASE-8369).
Konklusioner
Grænsefladen mellem HBase og Hive er ung, men har et godt potentiale. Der er en masse lavthængende frugter, der kan tages op for at gøre tingene nemmere og hurtigere. Det mest iøjnefaldende problem, der udelukker reel applikationsudvikling, er impedansmismatchet mellem Hives indtastede, tætte skema og HBases utyperede, sparsomme skema. Dette er lige så meget et kognitivt problem som et teknisk problem. Løsninger her ville tillade en række forbedringer at falde ud, herunder meget i vejen for ydeevneforbedringer. Jeg håber, at et fortsat arbejde med at tilføje datatyper til HBase (HBASE-8089) kan hjælpe med at bygge bro over denne kløft.
Grundlæggende operationer fungerer for det meste, i det mindste på en rudimentær måde. Du kan læse data ud af og skrive data tilbage til HBase ved hjælp af Hive. Konfiguration af miljøet er en uigennemsigtig og manuel proces, som sandsynligvis forhindrer nybegyndere i at anvende værktøjerne. Der er også spørgsmålet om masseoperationer – understøttelse til at skrive HF-filer og læse HBase-øjebliksbilleder ved hjælp af Hive mangler helt på dette punkt. Og selvfølgelig er der bugs drysset over. Den største seneste forbedring er udfasningen af HCatalogs grænseflade, hvilket fjerner den nødvendige forhåndsbeslutning om, hvilken grænseflade der skal bruges.
Hive giver en meget anvendelig SQL-grænseflade oven på HBase, en som let integreres i mange eksisterende ETL-arbejdsgange. Denne grænseflade kræver forenkling af noget af BigTable-semantikken, som HBase tilbyder, men resultatet vil være at åbne HBase for et meget bredere publikum af brugere. Hive interop komplimenterer ekstremt godt oplevelsen fra Phoenix. Hive har fordelen ved ikke at kræve de implementeringskompleksiteter, der i øjeblikket kræves af dette system. Forhåbentlig vil den almindelige definition af typer tillade en gratis fremtid.