sql >> Database >  >> NoSQL >> HBase

Apache HBase-regio splitsen en samenvoegen

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

Voor dit bericht duiken we technisch diep in een van de kerngebieden van HBase. In het bijzonder zullen we bekijken hoe Apache HBase de belasting verdeelt over regio's en regiosplitsing beheert. HBase slaat rijen met gegevens op in tabellen. Tabellen zijn opgesplitst in rijen die "regio's" worden genoemd. Die regio's worden gedistribueerd over het cluster, gehost en beschikbaar gemaakt voor clientprocessen door het RegionServer-proces. Een regio is een doorlopend bereik binnen de sleutelruimte, wat betekent dat alle rijen in de tabel die sorteren tussen de startsleutel en de eindsleutel van de regio in dezelfde regio worden opgeslagen. Regio's overlappen elkaar niet, d.w.z. een enkele rijsleutel hoort op elk moment bij precies één regio. Een regio wordt op elk moment alleen bediend door een enkele regioserver, en daarom garandeert HBase een sterke consistentie binnen een enkele rij#. Samen met de -ROOT- en .META. regio's, vormen de regio's van een tabel in feite een B-boom van 3 niveaus om een ​​rij binnen een tabel te lokaliseren.

Een regio bestaat op zijn beurt uit vele "winkels", die overeenkomen met kolomfamilies. Een winkel bevat één geheugenopslag en nul of meer opslagbestanden. De gegevens voor elke kolomfamilie worden afzonderlijk opgeslagen en geopend.

Een tabel bestaat doorgaans uit veel regio's, die op hun beurt worden gehost door veel regioservers. Regio's zijn dus het fysieke mechanisme dat wordt gebruikt om de schrijf- en querybelasting over regioservers te verdelen. Wanneer een tabel voor het eerst wordt gemaakt, wijst HBase standaard slechts één regio toe aan de tabel. Dit betekent dat in eerste instantie alle aanvragen naar een enkele regioserver gaan, ongeacht het aantal regioservers. Dit is de belangrijkste reden waarom de eerste fasen van het laden van gegevens in een lege tabel niet de volledige capaciteit van het cluster kunnen benutten.

Pre-splitsing

De reden dat HBase slechts één regio voor de tabel maakt, is dat het onmogelijk kan weten hoe de splitsingspunten binnen de rijsleutelruimte moeten worden gemaakt. Het nemen van dergelijke beslissingen is sterk gebaseerd op de verdeling van de sleutels in uw gegevens. In plaats van een gok te nemen en u de gevolgen te laten dragen, biedt HBase u wel tools om dit vanuit de klant te beheren. Met een proces dat pre-splitting wordt genoemd, kunt u een tabel met veel regio's maken door de splitsingspunten op te geven op het moment dat de tabel wordt gemaakt. Aangezien pre-splitsing ervoor zorgt dat de initiële belasting gelijkmatiger wordt verdeeld over het cluster, moet u altijd overwegen om het te gebruiken als u uw sleuteldistributie vooraf kent. Pre-splitsing brengt echter ook het risico met zich mee dat er regio's ontstaan ​​die de belasting niet echt gelijkmatig verdelen vanwege scheve gegevens, of in de aanwezigheid van zeer hete of grote rijen. Als de aanvankelijke set van regiosplitsingspunten slecht wordt gekozen, kan het zijn dat u een heterogene belastingsverdeling krijgt, wat op zijn beurt de prestaties van uw clusters zal beperken.

Er is geen kort antwoord voor het optimale aantal regio's voor een bepaalde belasting, maar u kunt beginnen met een lager veelvoud van het aantal regioservers als aantal splitsingen, en vervolgens geautomatiseerde splitsing voor de rest laten doen.

Een probleem met vooraf splitsen is het berekenen van de splitpunten voor de tafel. U kunt het hulpprogramma RegionSplitter gebruiken. RegionSplitter maakt de splitpunten met behulp van een pluggable SplitAlgorithm. HexStringSplit en UniformSplit zijn twee vooraf gedefinieerde algoritmen. De eerste kan worden gebruikt als de rijtoetsen een voorvoegsel hebben voor hexadecimale tekenreeksen (zoals wanneer u hashes als voorvoegsels gebruikt). De laatste verdeelt de sleutelruimte gelijkmatig, ervan uitgaande dat het willekeurige bytearrays zijn. U kunt ook uw aangepaste SplitAlgorithm implementeren en gebruiken vanuit het hulpprogramma RegionSplitter.

$ hbase org.apache.hadoop.hbase.util.RegionSplitter test_table HexStringSplit -c 10 -f f1

waarbij -c 10 het gevraagde aantal regio's specificeert als 10, en -f de kolomfamilies specificeert die u in de tabel wilt, gescheiden door ":". De tool maakt een tabel met de naam "test_table" met 10 regio's:

13/01/18 18:49:32 DEBUG hbase.HRegionInfo: Current INFO from scan results = {NAME => 'test_table,,1358563771069.acc1ad1b7962564fc3a43e5907e8db33.', STARTKEY => '', ENDKEY => '19999999', ENCODED => acc1ad1b7962564fc3a43e5907e8db33,}
13/01/18 18:49:32 DEBUG hbase.HRegionInfo: Current INFO from scan results = {NAME => 'test_table,19999999,1358563771096.37ec12df6bd0078f5573565af415c91b.', STARTKEY => '19999999', ENDKEY => '33333332', ENCODED => 37ec12df6bd0078f5573565af415c91b,}
...

Als je splitpunten bij de hand hebt, kun je ook de HBase-shell gebruiken om de tabel met de gewenste splitpunten te maken.

hbase(main):015:0> create 'test_table', 'f1', SPLITS=> ['a', 'b', 'c']

of

$ echo -e  "anbnc" >/tmp/splits
hbase(main):015:0> create 'test_table', 'f1', SPLITSFILE=>'/tmp/splits'

Voor een optimale verdeling van de belasting moet u nadenken over uw gegevensmodel en de sleutelverdeling voor het kiezen van het juiste splitsingsalgoritme of splitsingspunten. Ongeacht de methode die u hebt gekozen om de tabel te maken met een vooraf bepaald aantal regio's, u kunt nu beginnen met het laden van de gegevens in de tabel en zien dat de belasting over uw cluster wordt verdeeld. U kunt het automatisch splitsen het overnemen zodra de gegevensopname begint, en het totale aantal regio's voor de tabel continu controleren.

Automatisch splitsen

Ongeacht of pre-splitsing wordt gebruikt of niet, zodra een regio een bepaalde limiet bereikt, wordt deze automatisch in twee regio's gesplitst. Als u HBase 0.94 gebruikt (die wordt geleverd met HDP-1.2), kunt u configureren wanneer HBase besluit een regio te splitsen en hoe het de splitsingspunten berekent via de pluggable RegionSplitPolicy API. Er zijn een aantal vooraf gedefinieerde beleidsregels voor regiosplitsing:ConstantSizeRegionSplitPolicy, EnhanceToUpperBoundRegionSplitPolicy en KeyPrefixRegionSplitPolicy.

De eerste is het standaard en enige gesplitste beleid voor HBase-versies vóór 0.94. Het splitst de regio's wanneer de totale gegevensgrootte voor een van de winkels (overeenkomend met een kolomfamilie) in de regio groter wordt dan de geconfigureerde "hbase.hregion.max.filesize", die een standaardwaarde van 10 GB heeft. Dit splitsingsbeleid is ideaal in gevallen waarin u het pre-splitsen hebt gedaan en geïnteresseerd bent in een lager aantal regio's per regioserver.

Het standaardbeleid voor splitsen voor HBase 0.94 en trunk is stijgendeToUpperBoundRegionSplitPolicy, dat agressievere splitsingen uitvoert op basis van het aantal regio's dat wordt gehost op dezelfde regioserver. Het gesplitste beleid gebruikt de maximale bestandsgrootte van de winkel op basis van Min (R^2 * "hbase.hregion.memstore.flush.size", "hbase.hregion.max.filesize"), waarbij R het aantal regio's van dezelfde table gehost op dezelfde regionserver. Dus bijvoorbeeld, met de standaard opslaggrootte van 128 MB en de standaard maximale opslaggrootte van 10 GB, wordt de eerste regio op de regioserver gesplitst net na de eerste flush op 128 MB. Naarmate het aantal regio's dat op de regioserver wordt gehost, toeneemt, zal deze steeds grotere gesplitste groottes gebruiken:512 MB, 1152 MB, 2 GB, 3,2 GB, 4,6 GB, 6,2 GB, enz. Na het bereiken van 9 regio's, zal de gesplitste grootte verder gaan dan de geconfigureerde "hbase .hregion.max.filesize”, waarna vanaf dat moment een gesplitste grootte van 10 GB wordt gebruikt. Voor beide algoritmen, ongeacht wanneer het splitsen plaatsvindt, is het gebruikte splitspunt de rowkey die overeenkomt met het middelpunt in de "blokindex" voor het grootste winkelbestand in de grootste winkel.

KeyPrefixRegionSplitPolicy is een merkwaardige toevoeging aan het HBase-arsenaal. U kunt de lengte van het voorvoegsel voor uw rijsleutels configureren om ze te groeperen, en dit splitsingsbeleid zorgt ervoor dat de regio's niet worden gesplitst in het midden van een groep rijen met hetzelfde voorvoegsel. Als je voorvoegsels voor je sleutels hebt ingesteld, kun je dit split-beleid gebruiken om ervoor te zorgen dat rijen met hetzelfde voorvoegsel voor rijen altijd in dezelfde regio terechtkomen. Deze groepering van records wordt soms "Entiteitsgroepen" of "Rijgroepen" genoemd. Dit is een belangrijke functie bij het overwegen van het gebruik van de functie "lokale transacties" (alternatieve link) in uw applicatieontwerp.

U kunt het standaard gesplitste beleid configureren dat moet worden gebruikt door de configuratie "hbase.regionserver.region.split.policy" in te stellen of door de tabeldescriptor te configureren. Voor jullie dappere zielen, je kunt ook je eigen aangepaste split-beleid implementeren en dat aansluiten bij het maken van de tafel, of door een bestaande tafel aan te passen:

HTableDescriptor tableDesc = new HTableDescriptor("example-table");
tableDesc.setValue(HTableDescriptor.SPLIT_POLICY, AwesomeSplitPolicy.class.getName());
//add columns etc
admin.createTable(tableDesc);

Als u vooraf splitst en regiosplitsingen handmatig wilt beheren, kunt u regiosplitsingen ook uitschakelen door "hbase.hregion.max.filesize" in te stellen op een hoog aantal en het splitsbeleid in te stellen op ConstantSizeRegionSplitPolicy. U moet echter een beveiligingswaarde van ongeveer 100 GB gebruiken, zodat regio's niet verder groeien dan de mogelijkheden van een regioserver. U kunt overwegen om automatisch splitsen uit te schakelen en te vertrouwen op de initiële set regio's van pre-splitsing, bijvoorbeeld als u uniforme hashes gebruikt voor uw sleutelprefixen, en u kunt ervoor zorgen dat het lezen/schrijven naar elke regio wordt geladen, evenals de grootte ervan is uniform over de regio's in de tabel.

Geforceerde splitsingen

HBase stelt klanten ook in staat om een ​​online tafel geforceerd te splitsen vanaf de klantzijde. De HBase-shell kan bijvoorbeeld worden gebruikt om alle regio's van de tabel te splitsen, of een regio te splitsen, eventueel door een splitpunt op te geven.

hbase(main):024:0> split 'b07d0034cbe72cb040ae9cf66300a10c', 'b'
0 row(s) in 0.1620 seconds

Met zorgvuldige bewaking van uw HBase-belastingsverdeling en als u ziet dat sommige regio's ongelijke belastingen krijgen, kunt u overwegen om die regio's handmatig te splitsen om de belasting gelijkmatig te verdelen en de doorvoer te verbeteren. Een andere reden waarom u handmatige splitsingen wilt doen, is wanneer u ziet dat de initiële splitsingen voor de regio niet optimaal blijken te zijn en u automatische splitsingen hebt uitgeschakeld. Dat kan bijvoorbeeld gebeuren als de gegevensdistributie in de loop van de tijd verandert.

Hoe regio-splitsingen worden geïmplementeerd

Terwijl schrijfverzoeken worden afgehandeld door de regioserver, stapelen ze zich op in een in-memory opslagsysteem dat de "memstore" wordt genoemd. Zodra de geheugenopslag vol is, wordt de inhoud naar schijf geschreven als extra opslagbestanden. Deze gebeurtenis wordt een "memstore-flush" genoemd. Naarmate winkelbestanden zich ophopen, zal de RegionServer ze "compacteren" tot gecombineerde, grotere bestanden. Nadat elke spoeling of verdichting is voltooid, wordt een aanvraag voor regiosplitsing in de wachtrij geplaatst als het RegionSplitPolicy besluit dat de regio in tweeën moet worden gesplitst. Aangezien alle gegevensbestanden in HBase onveranderlijk zijn, zullen de nieuw gemaakte dochterregio's bij een splitsing niet alle gegevens in nieuwe bestanden herschrijven. In plaats daarvan maken ze kleine sym-link-achtige bestanden, genaamd Reference-bestanden, die verwijzen naar het bovenste of onderste deel van het bovenliggende winkelbestand volgens het splitspunt. Het referentiebestand wordt net als een regulier gegevensbestand gebruikt, maar slechts voor de helft van de records. De regio kan alleen worden gesplitst als er geen verwijzingen meer zijn naar de onveranderlijke gegevensbestanden van de bovenliggende regio. Die referentiebestanden worden geleidelijk opgeschoond door verdichtingen, zodat de regio niet langer naar zijn bovenliggende bestanden verwijst en verder kan worden opgesplitst.

Hoewel het splitsen van de regio een lokale beslissing is die op de RegionServer wordt genomen, moet het splitsproces zelf met veel actoren worden gecoördineerd. De RegionServer stelt de Master voor en na de splitsing op de hoogte, werkt de .META bij. tabel zodat clients de nieuwe dochterregio's kunnen ontdekken en de mapstructuur en gegevensbestanden in HDFS opnieuw rangschikt. Splitsen is een proces met meerdere taken. Om terugdraaien in het geval van een fout mogelijk te maken, houdt de RegionServer een dagboek bij over de uitvoeringsstatus in het geheugen. De stappen die door de RegionServer worden genomen om de splitsing uit te voeren, worden geïllustreerd in figuur 1. Elke stap is gelabeld met zijn stapnummer. Acties van RegionServers of Master worden in het rood weergegeven, terwijl acties van de clients groen worden weergegeven.

1. RegionServer besluit lokaal om de regio te splitsen en bereidt de splitsing voor. Als eerste stap maakt het een znode in zookeeper onder /hbase/regio-in-overgang/regio-naam in SPLITTING-status.
2. De Master leert over deze znode, omdat deze een watcher heeft voor de bovenliggende regio-in-overgang znode.
3. RegionServer maakt een submap met de naam ".splits" onder de bovenliggende regiomap in HDFS.
4. RegionServer sluit de bovenliggende regio, forceert een flush van de cache en markeert de regio als offline in zijn lokale gegevensstructuren. Op dit punt zullen clientverzoeken die naar de bovenliggende regio komen, NotServingRegionException genereren. De client zal het opnieuw proberen met wat uitstel.
5. RegionServer maakt de regiodirectory's onder de .splits-directory, voor dochterregio's A en B, en creëert de benodigde gegevensstructuren. Vervolgens splitst het de winkelbestanden, in die zin dat het twee referentiebestanden per winkelbestand in de bovenliggende regio maakt. Die referentiebestanden verwijzen naar de bovenliggende regiobestanden.
6. RegionServer maakt de eigenlijke regiomap in HDFS en verplaatst de referentiebestanden voor elke dochter.
7. RegionServer stuurt een Put-verzoek naar de .META. tabel en stelt de bovenliggende in als offline in de .META. tabel en voegt informatie toe over dochterregio's. Op dit moment zijn er geen individuele vermeldingen in .META. voor de dochters. Klanten zullen zien dat de bovenliggende regio is opgesplitst als ze .META. scannen, maar zullen niets weten over de dochters totdat ze verschijnen in .META.. Ook als dit op .META. slaagt, wordt de ouder effectief gesplitst. Als de RegionServer faalt voordat deze RPC slaagt, zullen Master en de volgende regioserver die de regio openen de vuile toestand over de regio-splitsing opschonen. Na de .META. update, zal de regio-splitsing echter door Master worden doorgevoerd.
8. RegionServer opent parallel dochters om schrijfbewerkingen te accepteren.
9. RegionServer voegt de dochters A en B toe aan .META. samen met informatie dat het de regio's herbergt. Na dit punt kunnen klanten de nieuwe regio's ontdekken en verzoeken indienen voor de nieuwe regio. Clients cachen de .META. vermeldingen lokaal, maar wanneer ze verzoeken indienen bij de regioserver of .META., worden hun caches ongeldig gemaakt en leren ze over de nieuwe regio's van .META..
10. RegionServer werkt znode /hbase/region-in-transition/regio-name in zookeeper bij om SPLIT te vermelden, zodat de master erover kan leren. De balancer kan de dochterregio's vrijelijk opnieuw toewijzen aan andere regioservers als hij daarvoor kiest.
11. Na de splitsing bevatten meta en HDFS nog steeds verwijzingen naar de bovenliggende regio. Die verwijzingen worden verwijderd wanneer verdichtingen in dochterregio's de gegevensbestanden herschrijven. Vuilnisophaaltaken in de master controleren periodiek of de dochterregio's nog verwijzen naar bovenliggende bestanden. Zo niet, dan wordt de bovenliggende regio verwijderd.

Regio fuseert

In tegenstelling tot het splitsen van regio's, biedt HBase op dit moment geen bruikbare tools voor het samenvoegen van regio's. Hoewel er HMerge- en Merge-tools zijn, zijn ze niet erg geschikt voor algemeen gebruik. Er is momenteel geen ondersteuning voor online tabellen en functionaliteit voor automatisch samenvoegen. Met problemen als OnlineMerge, door Master geïnitieerde automatische regio-samenvoegingen, op ZK gebaseerde lees-/schrijfvergrendelingen voor tabelbewerkingen, werken we echter aan het stabiliseren van regio-splitsingen en betere ondersteuning voor regio-samenvoegingen. Blijf op de hoogte!

Conclusie

Zoals u kunt zien, doet HBase onder de motorkap veel huishouding om regiosplitsingen te beheren en geautomatiseerde sharding door regio's te doen. HBase biedt echter ook de nodige tools rond regiobeheer, zodat u het splitsingsproces kunt beheren. U kunt ook precies bepalen wanneer en hoe regio-splitsingen plaatsvinden via een RegionSplitPolicy.

Het aantal regio's in een tabel en hoe die regio's zijn gesplitst, zijn cruciale factoren voor het begrijpen en afstemmen van uw HBase-clusterbelasting. Als u uw sleuteldistributie kunt schatten, moet u de tabel maken met pre-splitsing om de optimale initiële laadprestaties te krijgen. U kunt beginnen met een lager veelvoud van het aantal regioservers als startpunt voor het aanvankelijke aantal regio's, en geautomatiseerde splitsing het over laten nemen. Als u de aanvankelijke splitsingspunten niet correct kunt schatten, is het beter om de tabel met één regio te maken, en een eerste lading te starten met automatisch splitsen, en het verhogenToUpperBoundRegionSplitPolicy te gebruiken. Houd er echter rekening mee dat het totale aantal regio's in de loop van de tijd zal stabiliseren en dat de huidige set regiosplitsingspunten zal worden bepaald op basis van de gegevens die de tabel tot nu toe heeft ontvangen. Mogelijk wilt u de belastingsverdeling over de regio's te allen tijde controleren en als de belastingsverdeling in de loop van de tijd verandert, handmatige splitsing gebruiken of agressievere regio-indelingen instellen. Ten slotte kunt u de aanstaande online samenvoegfunctie uitproberen en uw gebruiksvoorbeeld bijdragen.


  1. Groepsarray na ontspannen en match

  2. De eenvoudigste manier om een ​​exemplaar van een mangoestdocument te kopiëren/klonen?

  3. Opgeslagen functie oproepen in mongodb

  4. Is er een manier om te voorkomen dat MongoDB meervoudsvormen toevoegt aan collectienamen?