Hive skillevægge og spande med eksempel
⚡ Smart opsummering
Partitioner og buckets er de to måder, Apache Hive opdeler tabeldata på disken: en partition opretter én mappe pr. nøgleværdi, mens en bucket hashes rækker til et fast antal filer.

Tabeller, partitioner og buckets er delene af Hive-datamodellering. En tabel definerer skemaet, en partition opdeler tabellen i mapper på disken, og en bucket opdeler dataene i en mappe i et fast antal filer.
Hvad er partitioner?
Hive-partitioner er en måde at organisere tabeller i partitioner ved at opdele tabeller i forskellige dele baseret på partitionsnøgler. Fysisk set er hver partition en separat undermappe under tabelmappen i HDFS, hvilket gør det muligt for Hive at springe data over, den ikke har brug for.
Partitionering er nyttigt, når tabellen har en eller flere partitionsnøgler. Partitionsnøgler er grundlæggende elementer til at bestemme, hvordan dataene gemmes i tabellen. En partitionsnøgle gemmes ikke i selve datafilerne – dens værdi er kodet i mappenavnet, så en forespørgsel, der filtrerer på den nøgle, kan kassere hele mapper, før en række læses. Dette kaldes partitionsbeskæring.
For eksempel: –
"Klienten har e-handelsdata, der tilhører indiske operationer, hvor hver statsoperation (38 stater) nævnes som en helhed. Hvis vi tager statskolonnen som partitionsnøgle og udfører partitioner på disse indiske data som helhed, kan vi få antallet af partitioner (38 partitioner), hvilket er lig med antallet af stater (38), der er til stede i Indien. Således at hver statsdata kan ses separat i partitionstabeller."
Prøve Code Snippet til partitioner
De seks nedenstående sætninger kører i rækkefølge i Hive-shellen. Hver af dem er et separat trin, og de følgende skærmbilleder viser den samme sekvens, der udføres på en live-klynge.
- Oprettelse af tabellen allstates
create table allstates(state string, District string,Enrolments string) row format delimited fields terminated by ',';
- Indlæser data i den oprettede tabel allstates
Load data local inpath '/home/hduser/Desktop/AllStates.csv' into table allstates;
- Oprettelse af partitionstabel
create table state_part(District string,Enrolments string) PARTITIONED BY(state string);
- Til partition skal vi indstille denne egenskab
set hive.exec.dynamic.partition.mode=nonstrict - Indlæser data i partitionstabel
INSERT OVERWRITE TABLE state_part PARTITION(state) SELECT district,enrolments,state from allstates;
- Faktisk behandling og dannelse af partitionstabeller baseret på tilstand som partitionsnøgle
Der vil være 38 partitionsoutput i HDFS-lageret med filnavnet som tilstandsnavn. Vi vil kontrollere dette i dette trin.
De følgende skærmbilleder viser udførelsen af ovennævnte kode.
På det første skærmbillede kører trin 1 ved bistade> prompt og skaber alle stater tabel med dens tre kolonner og et komma som feltafgrænser.
Det næste skærmbillede dækker trin 2 og 3: AllStates.csv-filen indlæses i alle staterog den partitionerede tabel delstatsdel oprettes med state deklareret som partitionsnøgle.
Trin 4 og 5 vises derefter. Dynamisk partitionstilstand er indstillet til ikke-strict, og INSERT OVERWRITE-sætningen starter et MapReduce-job, hvis loglinjer viser, at én partition indlæses for hver tilstandsværdi.
Listning af lagermappen i HDFS bekræfter resultatet af trin 6 – skallen rapporterer 38 elementer, et statsdel/stat= katalog pr. stat.
Fra ovenstående kode gør vi følgende ting
- Oprettelse af tabel allstates med 3 kolonnenavne såsom stat, distrikt og tilmeldinger
- Indlæser data i tabellen allstates
- Oprettelse af partitionstabel med tilstand som partitionsnøgle
- I dette trin indstilles partitionstilstanden som ikke-streng (denne tilstand aktiverer dynamisk partitionstilstand)
- Indlæser data i partitionstabellen state_part
- Faktisk behandling og dannelse af partitionstabeller baseret på tilstand som partitionsnøgle
- Der vil være 38 partitionsoutput i HDFS-lageret med filnavnet som tilstandsnavn. I dette trin ser vi de 38 partitionsoutput i HDFS.
Statisk vs. dynamisk partitionering i Hive
Det ovenstående eksempel bruger dynamisk partitionering, men Hive understøtter to indlæsningsstile, og forskellen bestemmer, hvor meget typing – og hvor stor risiko – hver last medfører.
Statisk partitionering navngiver partitionsværdien i selve sætningen, så værdien skal være kendt, før indlæsningen kører, og én sætning udfylder præcis én partition. Dynamisk partitionering lader Hive læse partitionsværdien ud af den sidste kolonne på SELECT-listen og oprette mapperne under kørsel, hvilket er grunden til, at eksemplet kun behøver en enkelt INSERT for at producere 38 mapper.
| Aspect | Statisk partitionering | Dynamisk partitionering |
|---|---|---|
| Partitionsværdi | Leveret manuelt i PARTITION-klausulen | Læs ved kørsel fra SELECT-kolonnen |
| Partitioner pr. sætning | Én | Mange |
| Konfiguration | Fungerer i standard streng tilstand | Skal hive.exec.dynamic.partition.mode indstilles til nonstrict |
| Indlæsningshastighed | Hurtigere, fordi der ikke er behov for værdiscanning | Langsommere, fordi jobbet grupperer rækker efter nøgle |
| Bedst egnet til | Små, kendte sæt såsom en daglig belastning | Store eller ukendte nøglesæt såsom 38 tilstande |
Dynamiske belastninger er også begrænsede. Hive begrænser, hvor mange partitioner ét job kan oprette – som standard 100 pr. mapper eller reducer og 1000 for hele sætningen – og jobbet mislykkes, når et af lofterne overskrides, så en nøgle med meget høj kardinalitet kræver, at disse grænser hæves, eller at der er et andet design.
Hvad er Buckets?
Buckets i Hive bruges til at adskille Hive-tabeldata i flere filer eller mapper. De bruges til effektiv forespørgsel, og i modsætning til en partition er antallet af buckets fast, når tabellen oprettes, så den aldrig vokser med dataene.
- Dataene, der findes i disse partitioner, kan yderligere opdeles i buckets (sække).
- Opdelingen udføres baseret på hash af bestemte kolonner, som vi har valgt i tabellen.
- Buckets bruger en form for hashing-algoritme i backend til at læse hver post og placere den i buckets.
- Den spand, en række lander i, bestemmes af hash_function(bucketing_column) mod num_buckets, så ens værdier altid lander i den samme fil
- På Hive 0.x og 1.x skulle bucketing aktiveres med sæt hive.enforce.bucketing=true; før indsættelsen
Den sidste indstilling er historik på en aktuel klynge: Apache Hive-manualen bemærker, at det ikke er nødvendigt fra Hive 2.x og fremefter, fordi motoren nu automatisk vælger reducer-antallet og cluster-by-kolonnen fra tabeldefinitionen.
Trin 1) Oprettelse af spand som vist nedenfor.
Skærmen nedenfor viser CREATE TABLE-sætningen for prøvespand, hvor CLUSTERED BY-klausulen nederst fastsætter antallet af buckets.
Fra ovenstående skærmbillede
- Vi opretter samplebucket med kolonnenavne som fornavn, job-id, afdeling, løn og land.
- Vi laver 4 spande herovre
- Når dataene er indlæst, placeres de automatisk i 4 buckets.
- Landekolonnen er klyngekolonnen, så hver række for ét land skrives til den samme bucket-fil
Trin 2) Indlæser data i tabellen samplebucket
Hvis vi antager, at tabellen "medarbejdere" allerede er oprettet i Hive-systemet, vil vi i dette trin se indlæsningen af data fra tabellen "medarbejdere" i tabellen "samplebucket".
Før vi begynder at flytte medarbejderdata til buckets, skal vi sørge for, at de består af kolonnenavne som fornavn, job-id, afdeling, løn og land.
Her indlæser vi data i samplebucket fra employeestabellen – skærmbilledet nedenfor viser INSERT OVERWRITE-sætningen, der udfører kopieringen.
Trin 3) Visning af de 4 buckets, der blev oprettet i trin 1
Hvis man viser tabelmappen i HDFS, vises det fysiske resultat: fire nummererede datafiler i stedet for én.
Fra ovenstående skærmbillede kan vi se, at dataene fra medarbejdertabellen overføres til de 4 buckets, der blev oprettet i trin 1.
Hive-partitionering vs. bucketing: Vigtigste forskelle
Begge funktioner deler en tabel op i mindre dele, men de gør det på forskellige niveauer i filsystemet, og de besvarer forskellige problemer. Tabellen nedenfor viser dem side om side.
| Punkt af sammenligning | Partitionering | Inddeling |
|---|---|---|
| Enhed oprettet | En mappe pr. nøgleværdi | En fil pr. hash-bucket |
| Erklæret med | OPDELT AF | KLYNGERET EFTER … I n SPANDE |
| Antal stykker | Vokser med antallet af forskellige værdier | Rettelse ved tabeloprettelse |
| Kolonne gemt i datafiler | Nej – værdien findes i mappenavnet | Ja – kolonnen forbliver en normal kolonne |
| Bedste kolonnetype | Lav kardinalitet, såsom stat, år eller land | Høj kardinalitet, såsom user_id eller transaction_id |
| Hovedfordel | Partitionsbeskæring springer unødvendige mapper over | Jævne filstørrelser, billig sampling og joins på kortsiden |
De to er ikke rivaler. Et almindeligt produktionslayout opdeler en faktatabel efter dato og bucketer derefter hver dag på join-nøglen, så en forespørgsel beskæres til én mappe og derefter joiner bucket-til-bucket indeni den.
Hvornår skal man bruge partitionering, bucketing eller begge dele
Valget mellem dem starter med kolonnens kardinalitet og formen på de forespørgsler, der læser tabellen.
- Partition når forespørgsler næsten altid filtrerer på den samme kolonne med lav kardinalitet, og når antallet af forskellige værdier forbliver i hundredvis i stedet for millioner
- Bucket når den nyttige kolonne har for mange forskellige værdier til at være en mappe, eller når tabellen joines eller samples gentagne gange på den kolonne.
- Brug begge dele for store faktatabeller: partitionering på datoen, derefter bucket inden for hver partition på join-nøglen
Den fejltilstand, man skal være opmærksom på, er problemet med små filer. Partitionering på en kolonne med meget høj kardinalitet – et tidsstempel eller et kunde-id – producerer tusindvis af små mapper, der hver indeholder en fil langt under HDFS-blokstørrelsen. Det oppuster NameNode-hukommelsen og gør hver scanning langsommere, hvilket er præcis det resultat, partitioneringen var ment til at forhindre. Bucketing undgår dette, fordi filantallet er begrænset af tabeldefinitionen.
Bucketing har sin egen advarsel: layoutet er kun korrekt, hvis alle forfattere overholder det. Det bucket-antal, der er deklareret ved oprettelsen, er metadata, så et job, der skriver til tabellen uden korrekt klyngedannelse, kan efterlade filer, der ikke matcher det deklarerede layout, og senere sampling eller bucket-joins vil læse de forkerte rækker.







