sql >> Database >  >> NoSQL >> HBase

Hive gebruiken om te communiceren met HBase, deel 1

Deze blogpost is gepubliceerd op Hortonworks.com vóór de fusie met Cloudera. Sommige links, bronnen of verwijzingen zijn mogelijk niet langer nauwkeurig.

Dit is de eerste van twee berichten waarin het gebruik van Hive voor interactie met HBase-tabellen wordt onderzocht. De tweede post is hier.

Een van de dingen waar ik vaak naar wordt gevraagd, is hoe je HBase van Apache Hive gebruikt. Niet alleen hoe u het moet doen, maar ook wat werkt, hoe goed het werkt en hoe u er goed gebruik van kunt maken. Ik heb wat onderzoek gedaan op dit gebied, dus hopelijk is dit nuttig voor iemand anders dan mijzelf. Dit is een onderwerp dat we niet hebben behandeld in HBase in Action, misschien worden deze opmerkingen de basis voor de 2e editie 😉 Deze opmerkingen zijn van toepassing op Hive 0.11.x die wordt gebruikt in combinatie met HBase 0.94.x. Ze zouden grotendeels van toepassing moeten zijn op 0.12.x + 0.96.x, hoewel ik nog niet alles heb getest.

Het Hive-project bevat een optionele bibliotheek voor interactie met HBase. Hier wordt de bruglaag tussen de twee systemen geïmplementeerd. De primaire interface die u gebruikt bij het openen van HBase vanuit Hive-query's, wordt de  BaseStorageHandler genoemd. . U kunt ook rechtstreeks communiceren met HBase-tabellen via de invoer- en uitvoerindelingen, maar de handler is eenvoudiger en werkt voor de meeste toepassingen.

HBase-tabellen van Hive

Gebruik de HBaseStorageHandler om HBase-tabellen te registreren bij de Hive-metastore. U kunt de HBase-tabel optioneel specificeren als EXTERNAL , in welk geval Hive niet maakt om die tabel rechtstreeks te laten vallen - u moet de HBase-shell gebruiken om dit te doen.

[sql]
MAAK [EXTERNE] TABEL foo(…)
OPGESLAGEN DOOR 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES ('hbase.table.name' =' bar');
[/sql]

De bovenstaande instructie registreert de HBase-tabel met de naam bar in de Hive-metastore, toegankelijk vanuit Hive onder de naam foo .

Onder de motorkap, HBaseStorageHandler delegeert interactie met de HBase-tabel aan
HiveHBaseTableInputFormat en HiveHBaseTableOutputFormat . U kunt uw HBase-tabel in Hive rechtstreeks met die klassen registreren als u dat wilt. De bovenstaande verklaring komt ongeveer overeen met:

[sql]
CREER TAFEL foo(…)
OPGESLAGEN ALS
INPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHBaseTableInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive .hbase.HiveHBaseTableOutputFormat'
TBLPROPERTIES ('hbase.table.name' ='bar');
[/sql]

Ook voorzien is het HiveHFileOutputFormat wat betekent dat het ook mogelijk moet zijn om HFiles te genereren voor bulkloading vanuit Hive. In de praktijk heb ik dit niet van begin tot eind werkend gekregen (zie HIVE-4627).

Schematoewijzing

Het registreren van de tafel is slechts de eerste stap. Als onderdeel van die registratie moet u ook een kolomtoewijzing opgeven. Zo koppelt u Hive-kolomnamen aan de rijsleutel en kolommen van de HBase-tabel. Doe dit met de hbase.columns.mapping SerDe-eigenschap.

[sql]
MAAK TABEL foo(rowkey STRING, a STRING, b STRING)
OPGESLAGEN DOOR 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
MET SERDEPROPERTIES ('hbase.columns .mapping' =':key,f:c1,f:c2')
TBLPROPERTIES ('hbase.table.name' ='bar');

[/sql]

De waarden in de toewijzingseigenschap komen één-op-één overeen met kolomnamen van de componenttabel. HBase-kolomnamen worden volledig gekwalificeerd per kolomfamilie en u gebruikt de speciale token :key om de rijsleutel te vertegenwoordigen. Het bovenstaande

voorbeeld maakt rijen uit de HBase-tabel bar beschikbaar via de Hive-tabel foo . De foo kolom rowkey verwijst naar de rowkey van de HBase-tabel, a naar c1 in de f kolomfamilie, en b naar c2 , ook in de f familie.

U kunt ook Hive's MAP . koppelen gegevensstructuren naar HBase-kolomfamilies. In dit geval wordt alleen de STRING Bijenkorftype wordt gebruikt. Het andere Hive-type dat momenteel wordt ondersteund, is BINARY . Zie de wiki-pagina voor meer voorbeelden.

Interactie met gegevens

Met de gedefinieerde kolomtoewijzingen hebt u nu toegang tot HBase-gegevens, net als andere Hive-gegevens. Momenteel worden alleen eenvoudige predikaten voor zoekopdrachten ondersteund.

[sql]
SELECTEER * VANAF foo WHERE …;
[/sql]

U kunt ook een HBase-tabel vullen met Hive. Dit werkt met zowel INTO en OVERWRITE clausules.

[sql]
VAN source_hive_table INVOER IN TAFEL my_hbase_table
SELECT source_hive_table.* WAAR …;
[/sql]

Houd er rekening mee dat er een regressie is in Hive 0.12.0 die deze functie verbreekt, zie HIVE-5515.

In de praktijk

Er is nog steeds een beetje finesse vereist om alles tijdens runtime goed te bekabelen. De HBase-interactiemodule is volledig optioneel, dus u moet ervoor zorgen dat deze en de HBase-afhankelijkheden beschikbaar zijn op het klassenpad van Hive.

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

De installatieomgeving kan dit voor gebruikers beter afhandelen, maar voorlopig moet u het zelf beheren. Idealiter de hive bin-script kan de aanwezigheid van HBase detecteren en automatisch de benodigde CLASSPATH . maken aanpassingen. Deze verbetering lijkt te worden bijgehouden in HIVE-2055. De last mile wordt verzorgd door de distributie zelf, zodat de omgevingsvariabelen zijn ingesteld voor hive . Deze functionaliteit wordt geleverd door BIGTOP-955.

U moet er ook voor zorgen dat de benodigde potten naar de MapReduce-taken worden verzonden wanneer u uw Hive-instructies uitvoert. Hive biedt een mechanisme voor het verzenden van extra taakafhankelijkheden via de auxjar-functie.

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

Ik heb een kleine bug ontdekt in HDP-1.3-builds die door de gebruiker opgegeven waarden van HIVE_AUX_JARS_PATH maskeert . Met beheerdersrechten is dit eenvoudig op te lossen door de regel in hive-env.sh te corrigeren een bestaande waarde respecteren. De
oplossing in gebruikersscripts is om de SET . te gebruiken statement om een ​​waarde op te geven zodra u de Hive CLI heeft gelanceerd.

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

Hive moet kunnen detecteren welke potten nodig zijn en deze zelf toevoegen. HBase levert de  TableMapReduceUtils#addDependencyJars  methoden hiervoor. Het lijkt erop dat dit wordt gedaan in hive-0.12.0, althans volgens HIVE-2379.

Toekomstig werk

Er is al veel gezegd over goede ondersteuning voor predikaat pushdown (HIVE-1643, HIVE-2854, HIVE-3617,
HIVE-3684) en bewustzijn van gegevenstypes (HIVE-1245, HIVE-2599). Deze gaan hand in hand, aangezien predikaatsemantiek wordt gedefinieerd in termen van de typen waarop ze werken. Er kan meer worden gedaan om de complexe gegevenstypen van Hive, zoals Maps en Structs, ook toe te wijzen aan HBase-kolomfamilies (HIVE-3211). Ondersteuning voor HBase-tijdstempels is een beetje een puinhoop; ze zijn niet beschikbaar voor Hive-apps met enige mate van granulariteit (HIVE-2828, HIVE-2306). De enige interactie die een gebruiker heeft, is de instelling van de opslaghandler voor het schrijven van een aangepaste tijdstempel met alle bewerkingen.

Vanuit prestatieperspectief zijn er dingen die Hive vandaag kan doen (dat wil zeggen, niet afhankelijk van gegevenstypen) om te profiteren van HBase. Er is ook de mogelijkheid van een HBase-bewuste Hive om gebruik te maken van HBase-tabellen als tussenliggende opslaglocatie (HIVE-3565), waardoor kaartzijdige samenvoegingen mogelijk worden met dimensietabellen die in HBase zijn geladen. Hive zou gebruik kunnen maken van de natuurlijke geïndexeerde structuur van HBase (HIVE-3634, HIVE-3727), waardoor mogelijk enorme scans worden bespaard. Momenteel heeft de gebruiker geen (enige?) controle over de scans die worden uitgevoerd. Configuratie per taak, of ten minste per tabel, moet worden ingeschakeld (HIVE-1233). Dat zou een HBase-bewuste gebruiker in staat stellen Hive hints te geven over hoe het moet communiceren met HBase. Ondersteuning voor eenvoudige split-sampling van HBase-tabellen (HIVE-3399) kan ook eenvoudig worden gedaan, omdat HBase al tabelpartities beheert.

Andere toegangskanalen

Voor alles wat tot nu toe is besproken, moest Hive communiceren met online HBase RegionServers. Toepassingen kunnen een aanzienlijke doorvoer behalen en profiteren van meer flexibiliteit door rechtstreeks te communiceren met HBase-gegevens die worden bewaard op HDFS. Dit heeft ook het voordeel dat Hive-workloads niet interfereren met online SLA-gebonden HBase-applicaties (tenminste, totdat we HBase-verbeteringen zien in QOS-isolatie tussen taken, HBASE-4441).

Zoals eerder vermeld, is er de HiveHFileOutputFormat . Het oplossen van HIVE-4627 zou Hive een eenvoudige manier moeten maken om HFiles te genereren voor bulklading. Nadat u de HFiles met Hive heeft gemaakt, is er nog de laatste stap van het uitvoeren van de
LoadIncrementalHFiles hulpprogramma om ze in de regio's te kopiëren en te registreren. Hiervoor is de HiveStorageHandler  interface heeft een soort hook nodig om het queryplan te beïnvloeden terwijl het is gemaakt, waardoor het stappen kan toevoegen. Eenmaal op zijn plaats moet het mogelijk zijn om SET een runtime-vlag, het wisselen van een INSERT  operatie om bulkload te gebruiken.

HBase heeft onlangs de functie voor snapshots van tabellen geïntroduceerd. Hierdoor kan een gebruiker een persistente point-in-time weergave van een tabel maken, die is opgeslagen in HDFS. HBase kan een tabel herstellen van een momentopname naar een eerdere staat en een geheel nieuwe tabel maken op basis van een bestaande momentopname. Hive biedt momenteel geen ondersteuning voor het lezen van een HBase-snapshot. Overigens ondersteunt HBase MapReduce-taken nog niet via snapshots, hoewel de functie nog in uitvoering is (HBASE-8369).

Conclusies

De interface tussen HBase en Hive is jong, maar heeft mooie potentie. Er is veel laaghangend fruit dat kan worden opgepikt om dingen gemakkelijker en sneller te maken. Het meest in het oog springende probleem dat echte applicatie-ontwikkeling verhindert, is de impedantie-mismatch tussen het getypte, dichte schema van Hive en het niet-getypeerde, schaarse schema van HBase. Dit is evenzeer een cognitief probleem als een technisch probleem. Oplossingen hier zouden een aantal verbeteringen mogelijk maken, waaronder veel prestatieverbeteringen. Ik hoop dat voortzetting van het werk om gegevenstypen toe te voegen aan HBase (HBASE-8089) deze kloof kan helpen overbruggen.

Basishandelingen werken meestal, althans op een rudimentaire manier. U kunt gegevens uitlezen uit en terugschrijven naar HBase met Hive. Het configureren van de omgeving is een ondoorzichtig en handmatig proces, een proces dat beginners er waarschijnlijk van weerhoudt de tools te gebruiken. Er is ook de kwestie van bulkbewerkingen - ondersteuning voor het schrijven van HFiles en het lezen van HBase-snapshots met Hive ontbreekt op dit moment volledig. En natuurlijk zijn er overal bugs gestrooid. De grootste recente verbetering is de afschaffing van de interface van HCatalog, waardoor de noodzakelijke beslissing vooraf over welke interface moet worden gebruikt, wordt verwijderd.

Hive biedt een zeer bruikbare SQL-interface bovenop HBase, een die gemakkelijk kan worden geïntegreerd in veel bestaande ETL-workflows. Die interface vereist vereenvoudiging van een deel van de BigTable-semantiek die HBase biedt, maar het resultaat zal zijn om HBase open te stellen voor een veel breder publiek van gebruikers. De Hive-interop is een uitstekende aanvulling op de ervaring van Phoenix. Hive heeft het voordeel dat de implementatiecomplexiteit die momenteel door dat systeem wordt vereist, niet nodig is. Hopelijk zorgt de algemene definitie van typen voor een aanvullende toekomst.


  1. MongoDB Toon huidige gebruiker

  2. wat is de beste strategie om gegevens tussen DB en redis-cache te synchroniseren?

  3. Mongodb voegt document in zonder _id-veld

  4. Redis Client List doel en beschrijving