6.1 Hvem oppfant HBase og hvorfor

I dette foredraget skal vi snakke om et så fantastisk verktøy som Hbase, som nylig har fått stor popularitet: Facebook bruker det for eksempel som grunnlag for meldingssystemet sitt, og dette sier allerede mye.

Foredraget vil snakke om konseptet Big Table og dets gratis implementering, funksjoner ved arbeid og forskjeller fra både klassiske relasjonsdatabaser (som MySQL og Oracle) og nøkkelverdilagringer som Redis, Aerospike og memcached. Som vanlig, la oss starte med historien til problemet. Som mange andre BigData-prosjekter ble Hbase født fra et konsept som ble utviklet av Google. Prinsippene bak Hbase ble beskrevet i Bigtable: A Distributed Storage System for Structured Data -artikkelen .

Som vi diskuterte i tidligere forelesninger, er vanlige filer ganske godt egnet for batchdatabehandling ved bruk av MapReduce-paradigmet. På den annen side er informasjon som er lagret i filer ganske upraktisk å oppdatere; Filer er også fratatt muligheten for tilfeldig tilgang. For raskt og praktisk arbeid med tilfeldig tilgang finnes det en klasse med nosql-systemer som nøkkelverdilagring, slik som Aerospike, Redis, Couchbase, Memcached. Imidlertid er batchbehandling vanligvis svært upraktisk i disse systemene. Hbase er et forsøk på å kombinere fordelene ved batchbehandling med bekvemmeligheten av oppdatering og tilfeldig tilgang.

6.2 Datamodell

HBase er en distribuert, kolonneorientert, multiversjon nøkkelverdidatabase.

  • Dataene er organisert i tabeller indeksert av en primærnøkkel kalt RowKey i Hbase.
  • For hver RowKey-nøkkel kan et ubegrenset sett med attributter (eller kolonner) lagres.
  • Kolonner er organisert i grupper av kolonner kalt kolonnefamilie. Som regel kombineres kolonner som har samme bruks- og lagringsmønster til én kolonnefamilie.
  • For hvert attributt kan flere forskjellige versjoner lagres. Ulike versjoner har forskjellig tidsstempel.

Oppføringer lagres fysisk i RowKey-sortert rekkefølge. I dette tilfellet lagres dataene som tilsvarer forskjellige kolonnefamilier separat, noe som gjør det mulig å lese data kun fra den ønskede kolonnefamilien om nødvendig.

Når et bestemt attributt slettes, slettes det ikke fysisk umiddelbart, men er kun merket med et spesielt gravsteinsflagg. Den fysiske slettingen av dataene vil skje senere, når den store komprimeringsoperasjonen utføres.

Attributter som tilhører samme kolonnegruppe og som tilsvarer samme nøkkel lagres fysisk som en sortert liste. Ethvert attributt kan være fraværende eller tilstede for hver nøkkel, og hvis attributtet er fraværende, forårsaker dette ikke overhead ved lagring av tomme verdier.

Liste- og kolonnegruppenavnene er faste og har en oversiktlig layout. På kolonnegruppenivå settes parametere som time to live (TTL) og maksimalt antall lagrede versjoner. Hvis forskjellen mellom tidsstemplet for en bestemt versjon og gjeldende tidspunkt er større enn TTL, merkes oppføringen for sletting. Hvis antall versjoner for et bestemt attributt overstiger maksimalt antall versjoner, merkes posten også for sletting.

Hbase-datamodellen kan huskes som en nøkkelverdi-match:

<table, RowKey, Column Family, Column, timestamp> -> Value

6.3 Støttede operasjoner

Listen over støttede operasjoner i hbase er ganske enkel. 4 hovedoperasjoner støttes:

  • Sett : legg til en ny oppføring i hbase. Tidsstemplet for denne oppføringen kan stilles inn for hånd, ellers settes den automatisk til gjeldende tid.
  • Hent : Hent data for en bestemt radnøkkel. Du kan spesifisere kolonnefamilien som vi skal ta dataene fra og antall versjoner vi ønsker å lese.
  • Skann : les postene én etter én. Du kan spesifisere posten som vi begynner å lese fra, posten som skal leses til, antall poster som skal leses, kolonnefamilien som lesingen skal utføres fra og maksimalt antall versjoner for hver post.
  • Slett : Merk en spesifikk versjon for sletting. Det vil ikke være noen fysisk sletting, den vil bli utsatt til neste større komprimering (se nedenfor).

6.4 Arkitektur

HBase er en distribuert database som kan kjøre på dusinvis eller hundrevis av fysiske servere, og sikrer uavbrutt drift selv om noen av dem mislykkes. Derfor er arkitekturen til HBase ganske kompleks sammenlignet med klassiske relasjonsdatabaser.

HBase bruker to hovedprosesser for sitt arbeid:

1. Regionserver – Betjener én eller flere regioner. En region er en rekke poster som tilsvarer et spesifikt utvalg av påfølgende radnøkler. Hver region inneholder:

  • Persistent Storage er den viktigste datalagringen i HBase. Dataene lagres fysisk på HDFS, i et spesielt HFile-format. Data i HFile lagres i RowKey-sortert rekkefølge. Ett par (region, kolonnefamilie) tilsvarer minst én HFIle.
  • MemStore - skrivebuffer. Siden dataene er lagret i HF-fil d i sortert rekkefølge, er det ganske dyrt å oppdatere HF-filen per post. I stedet, når du skriver, kommer data inn i et spesielt MemStore-minneområde, hvor det akkumuleres i noen tid. Når MemStore er fylt til en kritisk verdi, skrives dataene til en ny HFile.
  • BlockCache - cache for lesing. Lar deg spare tid betydelig på data som leses ofte.
  • Write Ahead Log (WAL) . Siden dataene skrives til memstore, er det en viss risiko for tap av data på grunn av et krasj. For å forhindre at dette skjer, faller alle operasjoner før den faktiske implementeringen av manipulasjonene inn i en spesiell loggfil. Dette lar deg gjenopprette data etter enhver feil.

2. Master Server - hovedserveren i HBase-klyngen. Mesteren administrerer fordelingen av regioner blant regionservere, fører et register over regioner, administrerer lanseringen av vanlige oppgaver og gjør annet nyttig arbeid.

For å koordinere handlinger mellom tjenester, bruker HBase Apache ZooKeeper, en spesialtjeneste designet for å administrere konfigurasjoner og synkronisere tjenester.

Når datamengden i regionen øker og den når en viss størrelse, starter Hbase splitt, en operasjon som deler regionen med 2. For å unngå konstante inndelinger av regioner, kan du forhåndsinnstille grensene for regionene og øke deres maksimum. størrelse.

Siden data for én region kan lagres i flere HFiles, slår Hbase dem sammen med jevne mellomrom for å fremskynde arbeidet. Denne operasjonen kalles komprimering i Hbase. Komprimeringer er av to typer:

  • Mindre komprimering . Starter automatisk, kjører i bakgrunnen. Har lav prioritet sammenlignet med andre Hbase-operasjoner.
  • Stor komprimering . Den startes for hånd eller ved forekomst av visse triggere (for eksempel av en timer). Den har høy prioritet og kan bremse klyngen betydelig. Store komprimeringer gjøres best på et tidspunkt da belastningen på klyngen er liten. Major Compaction sletter også fysisk data som tidligere er merket med gravstein.

6.5 Måter å jobbe med HBase på

HBase Shell

Den enkleste måten å komme i gang med Hbase på er å bruke hbase shell-verktøyet. Den er tilgjengelig umiddelbart etter installasjon av hbase på en hvilken som helst hbase-klyngenode.

Hbase shell er en jruby-konsoll med innebygd støtte for alle grunnleggende Hbase-operasjoner. Følgende er et eksempel på å lage en brukertabell med to kolonnefamilier, gjøre noen manipulasjoner på den og slippe tabellen på slutten i hbase-skallet:

create 'users', {NAME => 'user_profile', VERSIONS => 5}, {NAME => 'user_posts', VERSIONS => 1231231231} 
put 'users', 'id1', 'user_profile:name', 'alexander' 
put 'users', 'id1', 'user_profile:second_name', 'alexander' 
get 'users', 'id1' 
put 'users', 'id1', 'user_profile:second_name', 'kuznetsov' 
get 'users', 'id1' 
get 'users', 'id1', {COLUMN => 'user_profile:second_name', VERSIONS => 5} 
put 'users', 'id2', 'user_profile:name', 'vasiliy' 
put 'users', 'id2', 'user_profile:second_name', 'ivanov' 
scan 'users', {COLUMN => 'user_profile:second_name', VERSIONS => 5} 
delete 'users', 'id1', 'user_profile:second_name' 
get 'users', 'id1' 
disable 'users' 
drop 'users'

Native API

Som de fleste andre hadoop-relaterte prosjekter er hbase implementert i java, så den opprinnelige API-en er tilgjengelig i Java. Native API er ganske godt dokumentert på den offisielle nettsiden. Her er et eksempel på bruk av Hbase API hentet derfra:

import java.io.IOException;

import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

public class MyLittleHBaseClient {
  public static void main(String[] args) throws IOException {
	Configuration config = HBaseConfiguration.create();
	Connection connection = ConnectionFactory.createConnection(config);
	try {
  	Table table = connection.getTable(TableName.valueOf("myLittleHBaseTable"));
  	try {
    	Put p = new Put(Bytes.toBytes("myLittleRow"));
    	p.add(Bytes.toBytes("myLittleFamily"), Bytes.toBytes("someQualifier"),
    	Bytes.toBytes("Some Value"));
    	table.put(p);

    	Get g = new Get(Bytes.toBytes("myLittleRow"));
    	Result r = table.get(g);
    	byte [] value = r.getValue(Bytes.toBytes("myLittleFamily"),
      	Bytes.toBytes("someQualifier"));

    	String valueStr = Bytes.toString(value);
    	System.out.println("GET: " + valueStr);

    	Scan s = new Scan();
    	s.addColumn(Bytes.toBytes("myLittleFamily"), Bytes.toBytes("someQualifier"));
    	ResultScanner scanner = table.getScanner(s);
    	try {
       	for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
         	System.out.println("Found row: " + rr);
       	}
     	} finally {
       	scanner.close();
     	}
   	} finally {
     	if (table != null) table.close();
   	}
 	} finally {
   	connection.close();
 	}
  }
}

Sparsommelighet, REST og støtte for andre programmeringsspråk

For å jobbe fra andre programmeringsspråk tilbyr Hbase Thrift API og Rest API. Basert på dem er klienter bygget for alle store programmeringsspråk: python, PHP, Java Script, etc.

6.6 Noen funksjoner ved å jobbe med HBase

  1. Hbase integreres ut av esken med MapReduce, og kan brukes som input og output ved å bruke det spesielle TableInputFormat og TableOutputFormat.

  2. Det er veldig viktig å velge riktig RowKey. RowKey skal gi en god jevn fordeling på tvers av regioner, ellers risikerer man såkalte «hot regions» – regioner som brukes mye oftere enn andre, noe som fører til ineffektiv bruk av systemressurser.

  3. Hvis dataene ikke lastes opp enkeltvis, men umiddelbart i store partier, støtter Hbase en spesiell BulkLoad-mekanisme som lar deg laste opp data mye raskere enn å bruke enkle Puts. BulkLoad er i hovedsak en to-trinns operasjon:

    • Dannelse av HFile uten deltakelse av puts ved hjelp av en spesiell MapReduce-jobb
    • Setter inn disse filene direkte i Hbase
  4. Hbase støtter utsendelse av beregninger til Ganglia-overvåkingsserveren. Dette kan være svært nyttig når du administrerer Hbase for å komme til bunns i hbase-problemer.

radtast

RowKey er bruker-IDen, som er en GUUID, en streng spesielt generert for å være unik over hele verden. GUUID er fordelt jevnt, noe som gir en god fordeling av data på tvers av servere.

Kolonnefamilie

Vår lagring bruker to kolonnefamilier:

  • data. Denne gruppen av kolonner lagrer data som ikke lenger er relevante for reklameformål, for eksempel det faktum at en bruker har besøkt bestemte nettadresser. TTL for denne kolonnefamilien er satt til 2 måneder, grensen på antall versjoner er 2000.
  • lange data. Denne gruppen med kolonner lagrer data som ikke mister sin relevans over tid, for eksempel kjønn, fødselsdato og andre "evige" brukeregenskaper.

høyttalere

Hver type brukerfakta er lagret i en egen kolonne. Data:_v-kolonnen lagrer for eksempel nettadressene som er besøkt av brukeren, og LongData:kjønn-kolonnen lagrer brukerens kjønn.

Tidsstemplet for dette faktumet lagres som et tidsstempel. For eksempel, i Data:_v-kolonnen, er tidsstempelet tidspunktet brukeren besøkte en bestemt URL.

Denne lagringsstrukturen for brukerdata passer veldig godt med vårt bruksmønster og lar deg raskt oppdatere brukerdata, raskt få all nødvendig informasjon om brukere, og ved hjelp av MapReduce raskt behandle data om alle brukere samtidig.

6.7 Alternativer

HBase er ganske komplisert å administrere og bruke, så før du bruker HBase er det fornuftig å se på alternativene:

  • Relasjonsdatabaser . Et veldig godt alternativ, spesielt i tilfellet når dataene passer på én maskin. Først av alt bør du også tenke på relasjonsdatabaser i tilfelle transaksjoner av andre indekser enn de primære er viktige.

  • Oppbevaring av nøkkelverdi . Lagring som Redis og Aerospike er bedre egnet når ventetid er nødvendig og batchbehandling er mindre viktig.

  • Filer og deres behandling med MapReduce . Hvis dataene kun legges til og sjelden oppdateres/endres, så er det bedre å ikke bruke HBase, men bare lagre dataene i filer. For å forenkle arbeidet med filer kan du bruke verktøy som Hive, Pig og Impala.

Bruk av HBase er berettiget når:

  • Det er mye data, og de får ikke plass på én datamaskin/server
  • Data oppdateres og slettes ofte
  • Det er en eksplisitt "nøkkel" i dataene, som det er praktisk å binde alt annet til
  • Trenger batchbehandling
  • Trenger tilfeldig tilgang til data med spesifikke nøkler