Přepážky úlů a lopaty s příkladem
⚡ Chytré shrnutí
Oddíly a kontejnery jsou dva způsoby, jakými Apache Hive rozděluje data tabulek na disku: oddíl vytváří jeden adresář na hodnotu klíče, zatímco kontejner hašuje řádky do pevného počtu souborů.
Tabulky, oddíly a kontejnery jsou součástí modelování dat Hive. Tabulka definuje schéma, oddíl rozděluje tuto tabulku do adresářů na disku a kontejner rozděluje data uvnitř adresáře do pevně stanoveného počtu souborů.
Co je to oddíly?
Hive Partitions je způsob, jak uspořádat tabulky do oddílů rozdělením tabulek na různé části na základě klíčů oddílů. Fyzicky je každý oddíl samostatným podadresářem ve složce tabulky v HDFS, což umožňuje Hive přeskočit data, která nepotřebuje.
Rozdělení je užitečné, pokud tabulka obsahuje jeden nebo více klíčů oddílu. Klíče oddílu jsou základní prvky pro určení, jak jsou data uložena v tabulce. Klíč oddílu není uložen uvnitř samotných datových souborů – jeho hodnota je zakódována v názvu adresáře, takže dotaz filtrující tento klíč může zahodit celé adresáře před přečtením jakéhokoli řádku. Tomu se říká prořezávání oddílů.
Například: –
„Klient má data elektronického obchodování, která patří k operacím v Indii, ve kterých jsou všechny operace ve státě (38 států) uvedeny jako celek. Pokud vezmeme sloupec státu jako klíč oddílu a provedeme rozdělení na tato data v Indii jako celek, můžeme získat počet oddílů (38 oddílů), který se rovná počtu států (38) přítomných v Indii. Data každého státu lze tedy zobrazit samostatně v tabulkách oddílů.“
Vzorek Code Úryvek pro oddíly
Šest níže uvedených příkazů se v shellu Hive spustí postupně. Každý z nich představuje samostatný krok a následující snímky obrazovky ukazují stejnou sekvenci spouštěnou na aktivním clusteru.
- Vytvoření tabulky allstates
create table allstates(state string, District string,Enrolments string) row format delimited fields terminated by ',';
- Načítání dat do vytvořené tabulky allstates
Load data local inpath '/home/hduser/Desktop/AllStates.csv' into table allstates;
- Vytvoření tabulky oddílů
create table state_part(District string,Enrolments string) PARTITIONED BY(state string);
- Pro oddíl musíme tuto vlastnost nastavit
set hive.exec.dynamic.partition.mode=nonstrict - Načítání dat do tabulky oddílů
INSERT OVERWRITE TABLE state_part PARTITION(state) SELECT district,enrolments,state from allstates;
- Aktuální zpracování a tvorba tabulek oddílů na základě stavu jako klíč oddílu
V úložišti HDFS bude 38 výstupů oddílů s názvem souboru jako názvem stavu. V tomto kroku to ověříme.
Následující snímky obrazovky ukazují provedení výše uvedeného kódu.
Na první obrazovce probíhá krok 1 na úl> výzvu a vytvoří všechny státy tabulka se třemi sloupci a čárkou jako oddělovačem polí.
Následující obrazovka zahrnuje kroky 2 a 3: soubor AllStates.csv se načte do všechny státya rozdělená tabulka část_stavu je vytvořen se stavem deklarovaným jako klíčem oddílu.
Dále se zobrazí kroky 4 a 5. Režim dynamického oddílu je nastaven na nestriktní a příkaz INSERT OVERWRITE spustí úlohu MapReduce, jejíž řádky protokolu ukazují, že pro každou hodnotu stavu je načten jeden oddíl.
Výpis adresáře skladu v HDFS potvrzuje výsledek kroku 6 – shell hlásí 38 položek, jednu část_stavu/stav= adresář pro každý stát.
Z výše uvedeného kódu děláme následující věci
- Vytvoření tabulky allstates se 3 názvy sloupců, jako například stát, okres a počet studentů
- Načítání dat do tabulky allstates
- Vytvoření tabulky oddílů se stavem jako klíč oddílu
- V tomto kroku nastavte režim oddílů jako nestriktní (tento režim aktivuje dynamický režim oddílů)
- Načítání dat do tabulky oddílů state_part
- Aktuální zpracování a tvorba tabulek oddílů na základě stavu jako klíč oddílu
- V úložišti HDFS bude 38 výstupů oddílů s názvem souboru jako názvem stavu. V tomto kroku vidíme 38 výstupů oddílů v HDFS.
Statické vs. dynamické dělení v Hive
Výše uvedený příklad používá dynamické dělení, ale Hive podporuje dva styly načítání a rozdíl určuje, kolik typing – a kolik rizika – každý náklad nese.
Statické dělení pojmenuje hodnotu oddílu v samotném příkazu, takže hodnota musí být známá před spuštěním načítání a jeden příkaz vyplní přesně jeden oddíl. Dynamické dělení umožňuje Hive přečíst hodnotu oddílu z posledního sloupce seznamu SELECT a vytvořit adresáře za běhu, což je důvod, proč tento příklad potřebuje pouze jeden INSERT k vytvoření 38 adresářů.
| Vzhled | Statické dělení | Dynamické dělení |
|---|---|---|
| Hodnota oddílu | Ručně dodáváno v klauzuli PARTITION | Čtení za běhu ze sloupce SELECT |
| Oddíly na příkaz | Jedna | Mnoho |
| Konfigurace | Funguje ve výchozím striktním režimu | Vyžaduje nastavení hive.exec.dynamic.partition.mode na nonstrict. |
| Rychlost načítání | Rychlejší, protože není potřeba skenování hodnot | Pomalejší, protože úloha seskupuje řádky podle klíče |
| Nejlépe se hodí | Malé, známé sady, jako například denní zátěž | Velké nebo neznámé sady klíčů, například 38 států |
Dynamické zátěže jsou také omezeny. Hive omezuje počet oddílů, které může jedna úloha vytvořit – ve výchozím nastavení 100 na mapper nebo reducer a 1000 pro celý příkaz – a úloha selže, jakmile je překročen kterýkoli z těchto stropů, takže klíč s velmi vysokou mohutností potřebuje tyto limity zvýšit nebo jiný návrh.
Co je Buckets?
Buckety v Hive se používají k rozdělení dat tabulek Hive do více souborů nebo adresářů. Používají se pro efektivní dotazování a na rozdíl od oddílu je počet bucketů při vytváření tabulky pevně stanovený, takže nikdy neroste s daty.
- Data, která se nacházejí v těchto oddílech, lze dále rozdělit do segmentů (bucketů).
- Dělení se provádí na základě hashu konkrétních sloupců, které jsme v tabulce vybrali.
- Buckety používají na backendu nějaký hashovací algoritmus pro čtení každého záznamu a jeho umístění do bucketů.
- Do kterého segmentu řádek skončí, určuje hash_function(bucketing_column) mod num_buckets, takže stejné hodnoty se vždy dostanou do stejného souboru
- V Hive 0.x a 1.x muselo být bucketování povoleno pomocí nastavit hive.enforce.bucketing=true; před vložením
Toto poslední nastavení je historie na aktuálním clusteru: manuál k Apache Hive Poznamenává, že od verze Hive 2.x to není potřeba, protože engine nyní automaticky vybírá počet reduktorů a sloupec cluster-by z definice tabulky.
Krok 1) Vytvoření bucketu, jak je znázorněno níže.
Níže uvedená obrazovka zobrazuje příkaz CREATE TABLE pro vzorkovací kbelík, s klauzulí CLUSTERED BY ve spodní části, která opravuje počet segmentů.
Z výše uvedeného snímku obrazovky
- Vytváříme vzorkovací bucket s názvy sloupců, jako je křestní_jméno, ID_pracovní_pozice, oddělení, plat a země.
- Vytváříme zde 4 kbelíky
- Jakmile se data načtou, automaticky se umístí do 4 složek.
- Sloupec země je sloupcem shlukování, takže každý řádek pro jednu zemi je zapsán do stejného souboru bucket.
Krok 2) Načítání dat do tabulky samplebucket
Za předpokladu, že tabulka „employees“ je v systému Hive již vytvořena, uvidíme v tomto kroku načtení dat z tabulky employees do tabulky samplebucket.
Než začneme přesouvat data zaměstnanců do kontejnerů, ujistěte se, že obsahují názvy sloupců, jako je křestní_jméno, ID_pracovní_pozice, oddělení, plat a země.
Zde načítáme data do samplebucket z tabulky employees – níže uvedená obrazovka ukazuje příkaz INSERT OVERWRITE, který provádí kopírování.
Krok 3) Zobrazení 4 segmentů vytvořených v kroku 1
Výpis adresáře tabulek v HDFS ukazuje fyzický výsledek: čtyři číslované datové soubory místo jednoho.
Z výše uvedeného snímku obrazovky vidíme, že data z tabulky zaměstnanců jsou přenesena do 4 segmentů vytvořených v kroku 1.
Dělení podregistrů vs. bucketing: Klíčové rozdíly
Obě funkce rozdělují tabulku na menší části, ale dělají to na různých úrovních souborového systému a řeší různé problémy. Níže uvedená tabulka je srovnává.
| Bod srovnání | Rozdělení | Nakládání |
|---|---|---|
| Jednotka vytvořena | Adresář na hodnotu klíče | Soubor na hašovací bucket |
| Deklarováno s | ROZDĚLENO PODLE | SKLUSTROVÁNO … DO n KOLÍKŮ |
| Počet kusů | Roste s počtem odlišných hodnot | Opraveno při vytváření tabulky |
| Sloupec uložený v datových souborech | Ne – hodnota se nachází v názvu adresáře. | Ano – sloupec zůstane normálním sloupcem |
| Nejlepší typ sloupce | Nízká mohutnost, například stát, rok nebo země | Vysoká kardinalita, například user_id nebo transaction_id |
| Hlavní přínos | Prořezávání oddílů přeskakuje nepotřebné adresáře | Rovnoměrné velikosti souborů, levné vzorkování a spojení na straně mapy |
Tyto dva typy adresářů nejsou rivaly. Běžné produkční rozvržení rozděluje faktickou tabulku podle data a poté každý den na základě klíče spojení zařazuje do segmentů, takže dotaz se přesune do jednoho adresáře a poté se v něm spojí do segmentů.
Kdy použít dělení, bucketing nebo obojí
Výběr mezi nimi začíná mohutností sloupce a tvarem dotazů, které budou tabulku číst.
- Rozdělení když dotazy téměř vždy filtrují stejný sloupec s nízkou mohutností a když počet odlišných hodnot zůstává ve stovkách, nikoli v milionech
- Vědro když má užitečný sloupec příliš mnoho odlišných hodnot na to, aby mohl být adresářem, nebo když je tabulka v daném sloupci opakovaně spojována nebo vzorkována
- Použijte obě pro velké tabulky faktů: rozdělení na oddíl podle data a poté bucket uvnitř každého oddílu na klíči spojení
Režim selhání, na který je třeba dávat pozor, je problém malých souborů. Dělení na sloupci s velmi vysokou mohutností – časovým razítkem nebo identifikátorem zákazníka – vytváří tisíce malých adresářů, z nichž každý obsahuje soubor hluboko pod velikostí bloku HDFS. To nafukuje paměť NameNode a zpomaluje každé skenování, což je přesně ten výsledek, kterému mělo dělení zabránit. Bucketing se tomu vyhýbá, protože počet souborů je omezen definicí tabulky.
Bucketing má svou výhradu: rozvržení je správné pouze tehdy, pokud ho dodržují všichni zapisovači. Počet bucketů deklarovaný při vytváření jsou metadata, takže úloha, která zapisuje do tabulky bez správného shlukování, může zanechat soubory, které neodpovídají deklarovanému rozvržení, a pozdější vzorkování nebo spojení bucketů přečtou nesprávné řádky.








