Hive-partities en buckets met voorbeeld
โก Slimme samenvatting
Partities en buckets zijn de twee manieren waarop Apache Hive tabelgegevens op schijf verdeelt: een partitie creรซert รฉรฉn map per sleutelwaarde, terwijl een bucket rijen hasht in een vast aantal bestanden.

Tabellen, partities en buckets vormen de basis van Hive-datamodellering. Een tabel definieert het schema, een partitie verdeelt die tabel in mappen op de schijf en een bucket verdeelt de gegevens binnen een map in een vast aantal bestanden.
Wat zijn partities?
Hive-partities is een manier om tabellen in partities te organiseren door ze op te delen in verschillende delen op basis van partitiesleutels. Fysiek gezien is elke partitie een aparte subdirectory onder de tabelmap in HDFS, waardoor Hive gegevens kan overslaan die het niet nodig heeft.
Partitionering is nuttig wanneer een tabel een of meer partitiesleutels heeft. Partitiesleutels zijn essentiรซle elementen voor het bepalen hoe de gegevens in de tabel worden opgeslagen. Een partitiesleutel wordt niet in de gegevensbestanden zelf opgeslagen; de waarde ervan is gecodeerd in de mapnaam. Een query die filtert op die sleutel kan daardoor hele mappen negeren voordat er ook maar รฉรฉn rij wordt gelezen. Dit wordt partitiepruning genoemd.
Bijvoorbeeld: -
"De klant beschikt over e-commercegegevens van activiteiten in India, waarbij de activiteiten per staat (38 staten) als รฉรฉn geheel worden weergegeven. Als we de kolom 'staat' als partitiesleutel gebruiken en partities toepassen op deze Indiase gegevens, krijgen we 38 partities, gelijk aan het aantal staten (38) in India. Op deze manier kunnen de gegevens van elke staat afzonderlijk in de partitietabellen worden weergegeven."
Sample Code Fragment voor partities
De zes onderstaande instructies worden in de Hive-shell in volgorde uitgevoerd. Elke instructie is een aparte stap en de volgende schermafbeeldingen tonen dezelfde reeks die wordt uitgevoerd op een live cluster.
- Aanmaken van tabel allstates
create table allstates(state string, District string,Enrolments string) row format delimited fields terminated by ',';
- Gegevens laden in de aangemaakte tabel allstates
Load data local inpath '/home/hduser/Desktop/AllStates.csv' into table allstates;
- Aanmaken van partitietabel
create table state_part(District string,Enrolments string) PARTITIONED BY(state string);
- Voor partitie moeten we deze eigenschap instellen
set hive.exec.dynamic.partition.mode=nonstrict - Gegevens laden in partitietabel
INSERT OVERWRITE TABLE state_part PARTITION(state) SELECT district,enrolments,state from allstates;
- Feitelijke verwerking en vorming van partitietabellen op basis van de status als partitiesleutel
Er zullen 38 partitie-uitgangen in de HDFS-opslag zijn, waarbij de bestandsnaam de statusnaam is. We zullen dit in deze stap controleren.
De volgende schermafbeeldingen tonen de uitvoering van de bovengenoemde code.
In het eerste scherm wordt stap 1 uitgevoerd op het volgende niveau: bijenkorf> prompt en creรซert de alle staten Een tabel met drie kolommen en een komma als veldscheidingsteken.
Het volgende scherm toont stap 2 en 3: het bestand AllStates.csv wordt geladen in alle statenen de gepartitioneerde tabel staat_deel wordt aangemaakt met de status gedeclareerd als de partitiesleutel.
Stappen 4 en 5 volgen. De dynamische partitiemodus wordt ingesteld op 'niet-strikt' en de INSERT OVERWRITE-instructie start een MapReduce-taak waarvan de logregels laten zien dat er voor elke statuswaarde รฉรฉn partitie wordt geladen.
Het weergeven van de warehouse-directory in HDFS bevestigt het resultaat van stap 6: de shell meldt 38 items, waarvan รฉรฉn staat_deel/staat= directory per staat.
Vanuit de bovenstaande code doen we het volgende
- Het aanmaken van de tabel allstates met 3 kolomnamen: staat, district en inschrijvingen.
- Gegevens laden in tabel allstates
- Creรซren van partitietabel met status als partitiesleutel
- In deze stap wordt de partitiemodus ingesteld op 'niet-strikt' (deze modus activeert de dynamische partitiemodus).
- Gegevens laden in de partitietabel state_part
- Feitelijke verwerking en vorming van partitietabellen op basis van de status als partitiesleutel
- Er zullen 38 partitie-uitgangen in de HDFS-opslag zijn, waarbij de bestandsnaam de statusnaam is. In deze stap bekijken we de 38 partitie-uitgangen in HDFS.
Statische versus dynamische partitionering in Hive
Het bovenstaande voorbeeld maakt gebruik van dynamische partitionering, maar Hive ondersteunt twee laadstijlen en het verschil daartussen bepaalt hoeveel typing โ en hoeveel risico โ elke lading met zich meebrengt.
Statische partitionering De partitiewaarde wordt in de instructie zelf vermeld, dus de waarde moet bekend zijn voordat de laadbewerking wordt uitgevoerd en รฉรฉn instructie vult precies รฉรฉn partitie. Dynamische partitie Hierdoor kan Hive de partitiewaarde uit de laatste kolom van de SELECT-lijst lezen en de mappen tijdens de uitvoering aanmaken. Daarom is er in dit voorbeeld slechts รฉรฉn INSERT-instructie nodig om 38 mappen te genereren.
| Aspect | Statische partitionering | Dynamische partitie |
|---|---|---|
| Partitiewaarde | Handmatig verstrekt in de PARTITION-clausule | Lees tijdens de uitvoering uit de SELECT-kolom |
| Partities per verklaring | One | Veel |
| Configuratie | Werkt in de standaard strikte modus. | Vereist dat hive.exec.dynamic.partition.mode is ingesteld op nonstrict. |
| Laad snelheid | Sneller, omdat er geen waardescan nodig is. | Langzamer, omdat de taak rijen groepeert op basis van de sleutel. |
| Het meest geschikt voor: | Kleine, bekende sets, zoals een dagelijkse lading. | Grote of onbekende sleutelsets, zoals 38 staten. |
Dynamische loads hebben ook een limiet. Hive beperkt het aantal partities dat รฉรฉn taak mag aanmaken โ standaard 100 per mapper of reducer en 1000 voor de hele statement โ โโen de taak mislukt zodra een van deze limieten wordt overschreden. Daarom vereist een sleutel met een zeer hoge cardinaliteit een verhoging van deze limieten of een ander ontwerp.
Wat zijn emmers?
Buckets in Hive worden gebruikt om tabelgegevens in meerdere bestanden of mappen te verdelen. Ze zorgen voor efficiรซnte query's en, in tegenstelling tot een partitie, is het aantal buckets vastgelegd bij het aanmaken van de tabel, waardoor het nooit meegroeit met de hoeveelheid gegevens.
- De gegevens in die partities kunnen verder worden onderverdeeld in buckets.
- De deling wordt uitgevoerd op basis van de hash van specifieke kolommen die we in de tabel hebben geselecteerd.
- Buckets gebruiken een of ander hash-algoritme aan de achterkant om elk record te lezen en in de juiste bucket te plaatsen.
- In welke emmer een rij terechtkomt, wordt bepaald door hash_functie(bucketing_kolom) modulo aantal_buckets, zodat gelijke waarden altijd in hetzelfde bestand terechtkomen
- In Hive 0.x en 1.x moest bucketing ingeschakeld worden met set hive.enforce.bucketing=true; vรณรณr de invoeging
Die laatste instelling behoort tot het verleden op een huidig โโcluster: de Apache Hive-handleiding Merk op dat dit vanaf Hive 2.x niet meer nodig is, omdat de engine het aantal reducers en de kolom 'cluster-by' nu automatisch uit de tabeldefinitie haalt.
Stap 1) Maak een bucket zoals hieronder weergegeven.
Het onderstaande scherm toont de CREATE TABLE-instructie voor samplebucket, waarbij de CLUSTERED BY-clausule onderaan het aantal buckets vastlegt.
Uit de bovenstaande schermafdruk
- We maken een samplebucket aan met kolomnamen zoals first_name, job_id, department, salary en country.
- We maken hier 4 emmers.
- Zodra de gegevens geladen zijn, worden ze automatisch in 4 buckets geplaatst.
- De kolom 'land' is de clusterkolom, dus elke rij voor een bepaald land wordt naar hetzelfde bucketbestand geschreven.
Stap 2) Gegevens laden in tabel samplebucket
Ervan uitgaande dat de tabel "employees" al is aangemaakt in het Hive-systeem, zullen we in deze stap de gegevens uit de tabel "employees" in de tabel "samplebucket" laden.
Voordat we de werknemersgegevens in buckets gaan indelen, moeten we ervoor zorgen dat de buckets kolomnamen bevatten zoals first_name, job_id, department, salary en country.
Hier laden we gegevens uit de tabel 'employees' in de tabel 'samplebucket'. Het onderstaande scherm toont de INSERT OVERWRITE-instructie die de kopie uitvoert.
Stap 3) De 4 emmers die in stap 1 zijn gemaakt, worden weergegeven.
Als je de tabeldirectory in HDFS opvraagt, zie je het fysieke resultaat: vier genummerde gegevensbestanden in plaats van รฉรฉn.
Uit de bovenstaande schermafbeelding kunnen we zien dat de gegevens uit de tabel met werknemers worden overgezet naar de 4 buckets die in stap 1 zijn aangemaakt.
Hive-partitionering versus bucketing: belangrijkste verschillen
Beide functies verdelen een tabel in kleinere stukken, maar ze doen dit op verschillende niveaus van het bestandssysteem en ze bieden oplossingen voor verschillende problemen. De onderstaande tabel zet ze naast elkaar.
| Punt van vergelijking | Partitioning | Emmer |
|---|---|---|
| Eenheid gecreรซerd | Een map per sleutelwaarde | Een bestand per hash-bucket |
| Verklaard met | VERDEELD DOOR | GEGROEPEERD DOOR โฆ IN n EMMER |
| Aantal stukken | Groeit met het aantal verschillende waarden. | Vastgelegd tijdens het aanmaken van de tabel. |
| Kolom opgeslagen in gegevensbestanden | Nee, de waarde bevindt zich in de mapnaam. | Ja, de kolom blijft een normale kolom. |
| Beste kolomtype | Lage cardinaliteit, zoals staat, jaar of land | Hoge kardinaliteit, zoals user_id of transaction_id |
| Grootste voordeel | Partitieopschoning slaat onnodige mappen over. | Gelijkmatige bestandsgroottes, goedkope sampling en koppelingen aan de kaartzijde |
De twee zijn geen concurrenten. Een gangbare productielayout verdeelt een feitentabel op datum en groepeert vervolgens elke dag op basis van de koppelingssleutel, zodat een query de gegevens filtert tot รฉรฉn map en vervolgens de groepen daarbinnen samenvoegt.
Wanneer moet je partitionering, bucketing of beide gebruiken?
De keuze tussen beide begint met de cardinaliteit van de kolom en de structuur van de query's die de tabel zullen lezen.
- Tussenschot wanneer query's bijna altijd filteren op dezelfde kolom met een lage kardinaliteit, en wanneer het aantal unieke waarden in de honderden blijft in plaats van in de miljoenen.
- Emmer wanneer de nuttige kolom te veel verschillende waarden bevat om een โโdirectory te zijn, of wanneer de tabel herhaaldelijk wordt samengevoegd of bemonsterd op die kolom.
- Gebruik allebei Voor grote feitentabellen: partitioneer op de datum en maak vervolgens binnen elke partitie een bucket op basis van de koppelingssleutel.
Het probleem waar je op moet letten, is het probleem met de kleine bestanden. Partitioneren op een kolom met een zeer hoge kardinaliteit โ een tijdstempel of een klantidentificatie โ resulteert in duizenden kleine mappen, elk met een bestand dat veel kleiner is dan de HDFS-blokgrootte. Dit zorgt voor een overmatig geheugenverbruik van de NameNode en vertraagt โโelke scan, precies het resultaat dat partitionering juist moest voorkomen. Bucketing voorkomt dit, omdat het aantal bestanden wordt beperkt door de tabeldefinitie.
Het gebruik van buckets kent een eigen kanttekening: de indeling is alleen correct als elke schrijver zich eraan houdt. Het aantal buckets dat bij de aanmaak is opgegeven, is metadata. Een taak die naar de tabel schrijft zonder de juiste clustering toe te passen, kan bestanden achterlaten die niet overeenkomen met de opgegeven indeling. Latere sampling of het samenvoegen van buckets zal dan de verkeerde rijen lezen.







