Hive skillevegger og bøtter med eksempel
⚡ Smart oppsummering
Partisjoner og bøtter er de to måtene Apache Hive deler tabelldata på disk: en partisjon oppretter én katalog per nøkkelverdi, mens en bøtte hasher rader til et fast antall filer.

Tabeller, partisjoner og bøtter er delene av Hive-datamodellering. En tabell definerer skjemaet, en partisjon deler tabellen inn i kataloger på disken, og en bøtte deler dataene i en katalog inn i et fast antall filer.
Hva er partisjoner?
Hive-partisjoner er en måte å organisere tabeller i partisjoner ved å dele tabeller inn i forskjellige deler basert på partisjonsnøkler. Fysisk sett er hver partisjon en egen underkatalog under tabellmappen i HDFS, noe som gjør at Hive kan hoppe over data den ikke trenger.
Partisjonering er nyttig når tabellen har én eller flere partisjonsnøkler. Partisjonsnøkler er grunnleggende elementer for å bestemme hvordan dataene lagres i tabellen. En partisjonsnøkkel lagres ikke i selve datafilene – verdien er kodet i katalognavnet, så en spørring som filtrerer på den nøkkelen kan forkaste hele kataloger før noen rad leses. Dette kalles partisjonsbeskjæring.
For eksempel: –
«Klienten har e-handelsdata som tilhører indiske operasjoner der hver delstatsoperasjon (38 delstater) er nevnt som en helhet. Hvis vi tar delstatskolonnen som partisjonsnøkkel og utfører partisjoner på disse indiske dataene som en helhet, kan vi få antall partisjoner (38 partisjoner) som er lik antall delstater (38) som finnes i India. Slik at hver delstatsdata kan vises separat i partisjonstabeller.»
Eksempel Code Kodebit for partisjoner
De seks setningene nedenfor kjøres i rekkefølge i Hive-skallet. Hvert trinn er et separat trinn, og skjermbildene som følger viser samme sekvens som kjøres på en live-klynge.
- Oppretting av tabellen allstates
create table allstates(state string, District string,Enrolments string) row format delimited fields terminated by ',';
- Laster inn data i den opprettede tabellen allstates
Load data local inpath '/home/hduser/Desktop/AllStates.csv' into table allstates;
- Oppretting av partisjonstabell
create table state_part(District string,Enrolments string) PARTITIONED BY(state string);
- For partisjon må vi angi denne egenskapen
set hive.exec.dynamic.partition.mode=nonstrict - Laster data inn i partisjonstabell
INSERT OVERWRITE TABLE state_part PARTITION(state) SELECT district,enrolments,state from allstates;
- Faktisk behandling og dannelse av partisjonstabeller basert på tilstand som partisjonsnøkkel
Det vil være 38 partisjonsutganger i HDFS-lagring med filnavnet som tilstandsnavn. Vi vil sjekke dette i dette trinnet.
Følgende skjermbilder viser utførelsen av koden nevnt ovenfor.
I det første skjermbildet kjører trinn 1 på bikube> spørre og oppretter alle stater tabellen med de tre kolonnene og et komma som feltskilletegn.
Neste skjermbilde dekker trinn 2 og 3: AllStates.csv-filen lastes inn i alle stater, og den partisjonerte tabellen delstatsdel opprettes med state deklarert som partisjonsnøkkel.
Trinn 4 og 5 vises deretter. Dynamisk partisjonsmodus er satt til ikke-streng, og INSERT OVERWRITE-setningen starter en MapReduce-jobb der logglinjene viser at én partisjon lastes inn for hver tilstandsverdi.
Oppføring av lagerkatalogen i HDFS bekrefter resultatet av trinn 6 – skallet rapporterer 38 elementer, ett delstatsdel/delstat= katalog per stat.
Fra koden ovenfor gjør vi følgende ting
- Oppretting av tabellen allstates med 3 kolonnenavn som stat, distrikt og påmeldinger
- Laster inn data i tabellen allstates
- Oppretting av partisjonstabell med tilstand som partisjonsnøkkel
- I dette trinnet angir du partisjonsmodus som ikke-streng (denne modusen vil aktivere dynamisk partisjonsmodus)
- Laster inn data i partisjonstabellen state_part
- Faktisk behandling og dannelse av partisjonstabeller basert på tilstand som partisjonsnøkkel
- Det vil være 38 partisjonsutganger i HDFS-lagring med filnavnet som tilstandsnavn. I dette trinnet ser vi de 38 partisjonsutgangene i HDFS.
Statisk vs. dynamisk partisjonering i Hive
Det utarbeidede eksemplet ovenfor bruker dynamisk partisjonering, men Hive støtter to lastestiler, og forskjellen bestemmer hvor mye typing – og hvor mye risiko – hver last medfører.
Statisk partisjonering navngir partisjonsverdien i selve setningen, så verdien må være kjent før innlastingen kjører og én setning fyller nøyaktig én partisjon. Dynamisk partisjonering lar Hive lese partisjonsverdien ut av den siste kolonnen i SELECT-listen og opprette katalogene under kjøring, og det er derfor eksemplet bare trenger én enkelt INSERT for å produsere 38 kataloger.
| Aspekt | Statisk partisjonering | Dynamisk partisjonering |
|---|---|---|
| Partisjonsverdi | Leveres for hånd i PARTITION-klausulen | Les under kjøring fra SELECT-kolonnen |
| Partisjoner per setning | En | Mange |
| Konfigurasjon | Fungerer i standard streng modus | Krever at hive.exec.dynamic.partition.mode er satt til nonstrict |
| Last hastighet | Raskere, fordi ingen verdiskanning er nødvendig | Tregere, fordi jobben grupperer rader etter nøkkel |
| Passer best til | Små, kjente sett som en daglig belastning | Store eller ukjente nøkkelsett, for eksempel 38 tilstander |
Dynamiske belastninger er også begrenset. Hive begrenser hvor mange partisjoner én jobb kan opprette – som standard 100 per mapper eller reducer og 1000 for hele setningen – og jobben mislykkes når et av takene krysses, så en nøkkel med svært høy kardinalitet trenger at disse grensene heves eller et annet design.
Hva er Bøtter?
Bøtter i Hive brukes til å separere Hive-tabelldata i flere filer eller mapper. De brukes til effektiv spørring, og i motsetning til en partisjon er antallet bøtter fast når tabellen opprettes, slik at den aldri vokser med dataene.
- Dataene som finnes i disse partisjonene kan deles videre inn i bøtter
- Delingen utføres basert på hash av bestemte kolonner som vi valgte i tabellen.
- Bøtter bruker en eller annen form for hashing-algoritme i bakenden for å lese hver post og plassere den i bøtter.
- Hvilken bøtte en rad lander i bestemmes av hash_function(bucketing_column) mod num_buckets, slik at like verdier alltid havner i samme fil
- På Hive 0.x og 1.x måtte bucketing aktiveres med sett hive.enforce.bucketing=true; før innsatsen
Den siste innstillingen er historikk på en gjeldende klynge: Apache Hive-manualen bemerker at det ikke er nødvendig fra Hive 2.x og utover, fordi motoren nå automatisk velger reduksjonsantallet og klynge-etter-kolonnen fra tabelldefinisjonen.
Trinn 1) Lage bøtte som vist nedenfor.
Skjermbildet nedenfor viser CREATE TABLE-setningen for prøvebøtte, med CLUSTERED BY-klausulen nederst som fastsetter antall bøtter.
Fra skjermbildet ovenfor
- Vi lager samplebucket med kolonnenavn som fornavn, jobb-id, avdeling, lønn og land.
- Vi lager fire bøtter her borte
- Når dataene er lastet inn, plasseres de automatisk i fire bøtter.
- Landkolonnen er klyngekolonnen, så hver rad for ett land skrives til den samme bucket-filen
Trinn 2) Laster inn data i tabellens eksempelbøtte
Forutsatt at tabellen «ansatte» allerede er opprettet i Hive-systemet, vil vi i dette trinnet se lasting av data fra tabellen «ansatte» til tabellen «samplebucket».
Før vi begynner å flytte ansattes data til bøtter, må vi sørge for at de består av kolonnenavn som fornavn, jobb-id, avdeling, lønn og land.
Her laster vi inn data i samplebucket fra employees-tabellen – skjermbildet nedenfor viser INSERT OVERWRITE-setningen som utfører kopieringen.
Trinn 3) Viser de fire bøttene som ble opprettet i trinn 1
Å liste opp tabellkatalogen i HDFS viser det fysiske resultatet: fire nummererte datafiler i stedet for én.
Fra skjermbildet ovenfor kan vi se at dataene fra ansatt-tabellen overføres til de fire bøttene som ble opprettet i trinn 1.
Hive-partisjonering vs. bucketing: Viktige forskjeller
Begge funksjonene deler en tabell opp i mindre deler, men de gjør det på forskjellige nivåer i filsystemet og de svarer på forskjellige problemer. Tabellen nedenfor setter dem side om side.
| Sammenligningspunkt | Oppdeling | Inndeling av buckets |
|---|---|---|
| Enhet opprettet | En katalog per nøkkelverdi | En fil per hash-bøtte |
| Erklært med | DELT AV | KLUSTERT ETTER … I n BØTTER |
| Antall stykker | Vokser med antallet distinkte verdier | Fikset ved tabelloppretting |
| Kolonne lagret i datafiler | Nei – verdien ligger i katalognavnet | Ja – kolonnen forblir en vanlig kolonne |
| Beste kolonnetype | Lav kardinalitet, for eksempel stat, år eller land | Høy kardinalitet, for eksempel bruker-ID eller transaksjons-ID |
| Hovedfordel | Partisjonsrensing hopper over unødvendige mapper | Jevn filstørrelse, billig sampling og sammenføyninger på kartsiden |
De to er ikke rivaler. Et vanlig produksjonsoppsett partisjonerer en faktatabell etter dato og deler deretter inn hver dag på join-nøkkelen, slik at en spørring beskjærer til én katalog og deretter kobler sammen bøtte-til-bøtte inni den.
Når du skal bruke partisjonering, bucketing eller begge deler
Valget mellom dem starter med kolonnens kardinalitet og formen på spørringene som skal lese tabellen.
- Partisjon når spørringer nesten alltid filtrerer på den samme kolonnen med lav kardinalitet, og når antallet distinkte verdier holder seg i hundrevis i stedet for millioner
- Bucket når den nyttige kolonnen har for mange forskjellige verdier til å være en katalog, eller når tabellen blir koblet sammen eller samplet gjentatte ganger på den kolonnen
- Bruk begge deler for store faktatabeller: partisjoner på datoen, deretter bucket inni hver partisjon på join-nøkkelen
Feilmodusen man må se etter er problemet med små filer. Partisjonering på en kolonne med svært høy kardinalitet – et tidsstempel eller en kundeidentifikator – produserer tusenvis av bittesmå mapper, som hver inneholder en fil langt under HDFS-blokkstørrelsen. Dette blåser opp NameNode-minnet og gjør hver skanning tregere, noe som er akkurat det resultatet partisjoneringen var ment å forhindre. Bucketing unngår dette fordi filantallet er begrenset av tabelldefinisjonen.
Bucketing har sitt eget forbehold: layouten er bare korrekt hvis alle forfattere overholder den. Bucket-antall som er deklarert ved opprettelse er metadata, så en jobb som skriver til tabellen uten å gruppere riktig kan etterlate filer som ikke samsvarer med den deklarerte layouten, og senere sampling eller bucket-koblinger vil lese feil rader.







