Przegrody i wiadra ula z przykładem
⚡ Inteligentne podsumowanie
Partycje i kontenery to dwa sposoby, w jakie Apache Hive dzieli dane tabelaryczne na dysku: partycja tworzy jeden katalog na wartość klucza, podczas gdy kontener haszuje wiersze do ustalonej liczby plików.
Tabele, partycje i kontenery to elementy modelowania danych Hive. Tabela definiuje schemat, partycja dzieli tę tabelę na katalogi na dysku, a kontener dzieli dane w katalogu na ustaloną liczbę plików.
Co to jest partycje?
Hive Partitions to sposób na organizowanie tabel w partycje poprzez podział tabel na różne części na podstawie kluczy partycji. Fizycznie każda partycja jest oddzielnym podkatalogiem w folderze tabeli w systemie HDFS, co pozwala Hive pominąć dane, których nie potrzebuje.
Partycjonowanie jest pomocne, gdy tabela ma jeden lub więcej kluczy partycji. Klucze partycji to podstawowe elementy określające sposób przechowywania danych w tabeli. Klucz partycji nie jest przechowywany w samych plikach danych – jego wartość jest zakodowana w nazwie katalogu, więc zapytanie filtrujące według tego klucza może odrzucić całe katalogi przed odczytaniem jakiegokolwiek wiersza. Nazywa się to przycinaniem partycji.
Na przykład: -
„Klient posiada dane dotyczące handlu elektronicznego, które należą do operacji w Indiach, w których operacje każdego stanu (38 stanów) są wymienione jako całość. Jeśli weźmiemy kolumnę stanu za klucz partycji i przeprowadzimy partycjonowanie danych dla Indii jako całości, możemy uzyskać liczbę partycji (38 partycji), która jest równa liczbie stanów (38) obecnych w Indiach. Dzięki temu dane dla każdego stanu można przeglądać osobno w tabelach partycji.”
Próba Code Fragment kodu dla partycji
Sześć poniższych poleceń jest uruchamianych w kolejności w powłoce Hive. Każde z nich to osobny krok, a poniższe zrzuty ekranu pokazują tę samą sekwencję poleceń wykonywanych w aktywnym klastrze.
- Tworzenie tabeli allstates
create table allstates(state string, District string,Enrolments string) row format delimited fields terminated by ',';
- Ładowanie danych do utworzonej tabeli allstates
Load data local inpath '/home/hduser/Desktop/AllStates.csv' into table allstates;
- Utworzenie tablicy partycji
create table state_part(District string,Enrolments string) PARTITIONED BY(state string);
- W przypadku partycji musimy ustawić tę właściwość
set hive.exec.dynamic.partition.mode=nonstrict - Ładowanie danych do tablicy partycji
INSERT OVERWRITE TABLE state_part PARTITION(state) SELECT district,enrolments,state from allstates;
- Rzeczywiste przetwarzanie i tworzenie tablic partycji na podstawie stanu jako klucza partycji
W pamięci masowej HDFS będzie 38 wyjść partycji, których nazwa pliku będzie nazwą stanu. Sprawdzimy to w tym kroku.
Poniższe zrzuty ekranu pokazują wykonanie powyższego kodu.
Na pierwszym ekranie krok 1 jest wykonywany w ul> podpowiada i tworzy wszystkie stany tabela z trzema kolumnami i przecinkiem jako rozgranicznikiem pól.
Następny ekran obejmuje kroki 2 i 3: plik AllStates.csv jest ładowany do wszystkie stanyi partycjonowaną tabelę część_stanu zostaje utworzony ze stanem zadeklarowanym jako klucz partycji.
Następnie pojawiają się kroki 4 i 5. Tryb partycji dynamicznej jest ustawiany na nieskrępowany, a polecenie INSERT OVERWRITE uruchamia zadanie MapReduce, którego wiersze dziennika pokazują, że dla każdej wartości stanu ładowana jest jedna partycja.
Wyświetlenie katalogu magazynu w systemie HDFS potwierdza wynik kroku 6 – powłoka raportuje 38 pozycji, jedną część_stanu/stan= katalog według stanu.
Na podstawie powyższego kodu wykonujemy następujące czynności
- Utworzenie tabeli allstates z 3 nazwami kolumn, takimi jak stan, okręg i zapisy
- Ładowanie danych do tabeli allstates
- Utworzenie tablicy partycji ze stanem jako kluczem partycji
- W tym kroku ustaw tryb partycjonowania na nieścisły (ten tryb aktywuje dynamiczny tryb partycjonowania)
- Ładowanie danych do tabeli partycji state_part
- Rzeczywiste przetwarzanie i tworzenie tablic partycji na podstawie stanu jako klucza partycji
- W pamięci masowej HDFS będzie 38 wyjść partycji, których nazwa pliku będzie nazwą stanu. W tym kroku zobaczymy 38 wyjść partycji w HDFS.
Partycjonowanie statyczne a dynamiczne w Hive
Powyższy przykład roboczy wykorzystuje partycjonowanie dynamiczne, ale Hive obsługuje dwa style ładowania, a różnica decyduje o tym, ileping – i jakie ryzyko niesie ze sobą każdy ładunek.
Partycjonowanie statyczne podaje wartość partycji w samym poleceniu, więc wartość musi być znana przed uruchomieniem ładowania, a jedno polecenie wypełnia dokładnie jedną partycję. Partycjonowanie dynamiczne pozwala Hive odczytać wartość partycji z ostatniej kolumny listy SELECT i utworzyć katalogi w czasie wykonywania, dlatego przykład wymaga tylko jednego polecenia INSERT do wygenerowania 38 katalogów.
| WYGLĄD | Partycjonowanie statyczne | Partycjonowanie dynamiczne |
|---|---|---|
| Wartość partycji | Dostarczone ręcznie w klauzuli PARTITION | Odczyt w czasie wykonywania z kolumny SELECT |
| Partycje na polecenie | jeden | Wiele |
| Konfiguracja | Działa w domyślnym trybie ścisłym | Wymaga ustawienia hive.exec.dynamic.partition.mode na nonstrict |
| Prędkość ładowania | Szybciej, bo nie jest potrzebne skanowanie wartości | Wolniej, ponieważ zadanie grupuje wiersze według klucza |
| Najlepiej nadaje się do | Małe, znane zestawy, takie jak obciążenie dzienne | Duże lub nieznane zestawy kluczy, takie jak 38 stanów |
Obciążenia dynamiczne również podlegają limitom. Hive ogranicza liczbę partycji, które może utworzyć jedno zadanie – domyślnie 100 na maper lub reduktor i 1000 na całe polecenie – a zadanie kończy się niepowodzeniem po przekroczeniu któregokolwiek z limitów, więc klucz o bardzo wysokiej kardynalności wymaga podniesienia tych limitów lub innej konstrukcji.
Co to jest Wiadra?
Kontenery w Hive służą do segregowania danych tabel Hive na wiele plików lub katalogów. Służą one do wydajnego wykonywania zapytań i, w przeciwieństwie do partycji, liczba kontenerów jest stała w momencie tworzenia tabeli, więc nigdy nie rośnie wraz z danymi.
- Dane znajdujące się w tych partycjach można dalej podzielić na grupy
- Podział wykonujemy na podstawie hasha poszczególnych kolumn, które wybraliśmy w tabeli
- Kontenery wykorzystują pewną formę algorytmu haszującego w zapleczu, aby odczytać każdy rekord i umieścić go w kontenerach
- Do którego koszyka trafi dany rząd, decyduje funkcja_hash(kolumna_bucketingowa) mod num_buckets, więc równe wartości zawsze trafiają do tego samego pliku
- W wersjach Hive 0.x i 1.x konieczne było włączenie grupowania ustaw hive.enforce.bucketing=true; przed włożeniem
Ostatnie ustawienie to historia bieżącego klastra: podręcznik Apache Hive zauważa, że nie jest to konieczne od wersji Hive 2.x, ponieważ silnik automatycznie pobiera liczbę reduktorów i klaster według kolumny z definicji tabeli.
Krok 1) Tworzenie wiadra, jak pokazano poniżej.
Poniższy ekran pokazuje polecenie CREATE TABLE dla wiadro próbek, przy czym klauzula CLUSTERED BY na dole ustala liczbę kubełków.
Z powyższego zrzutu ekranu
- Tworzymy samplebucket z nazwami kolumn takimi jak imię, identyfikator zadania, dział, wynagrodzenie i kraj
- Tutaj tworzymy 4 wiadra
- Po załadowaniu danych dane są automatycznie umieszczane w 4 grupach
- Kolumna kraju jest kolumną klastrowania, więc każdy wiersz dla jednego kraju jest zapisywany w tym samym pliku kontenera
Krok 2) Ładowanie danych do tabeli samplebucket
Zakładając, że tabela „employees” została już utworzona w systemie Hive, w tym kroku zobaczymy ładowanie danych z tabeli employees do tabeli samplebucket.
Zanim zaczniemy przenosić dane pracowników do kontenerów, upewnijmy się, że zawierają one nazwy kolumn, takie jak imię, identyfikator zadania, dział, wynagrodzenie i kraj.
Tutaj ładujemy dane do samplebucket z tabeli employees — poniższy ekran pokazuje polecenie INSERT OVERWRITE, które wykonuje kopiowanie.
Krok 3) Wyświetlanie 4 kontenerów utworzonych w kroku 1
Wypisanie katalogu tabel w systemie HDFS pokazuje fizyczny wynik: cztery ponumerowane pliki danych zamiast jednego.
Na powyższym zrzucie ekranu możemy zobaczyć, że dane z tabeli pracowników są przesyłane do 4 kontenerów utworzonych w kroku 1.
Partycjonowanie Hive a grupowanie: kluczowe różnice
Obie funkcje dzielą tabelę na mniejsze fragmenty, ale robią to na różnych poziomach systemu plików i rozwiązują różne problemy. Poniższa tabela zestawia je obok siebie.
| Punkt porównania | Partycjonowanie | Wiadro |
|---|---|---|
| Jednostka utworzona | Katalog na wartość klucza | Plik na kontener haszujący |
| Zadeklarowano z | Podzielone przez | ZGRUPOWANE PRZEZ… W WIADRA |
| Liczba kawałków | Rośnie wraz z liczbą odrębnych wartości | Naprawiono podczas tworzenia tabeli |
| Kolumna przechowywana w plikach danych | Nie – wartość znajduje się w nazwie katalogu | Tak – kolumna pozostaje normalną kolumną |
| Najlepszy typ kolumny | Niska kardynalność, np. stan, rok lub kraj | Wysoka kardynalność, np. user_id lub transaction_id |
| Główna korzyść | Przycinanie partycji pomija niepotrzebne katalogi | Nawet rozmiary plików, tanie próbkowanie i łączenia po stronie mapy |
Te dwie metody nie są ze sobą rywalami. Typowy układ produkcyjny partycjonuje tabelę faktów według daty, a następnie każdego dnia dzieli ją na segmenty według klucza łączenia, więc zapytanie przycina dane do jednego katalogu, a następnie łączy segmenty w jego obrębie.
Kiedy używać partycjonowania, grupowania czy obu tych metod
Wybór między nimi zaczyna się od kardynalności kolumny i kształtu zapytań, które będą odczytywać tabelę.
- przegroda gdy zapytania prawie zawsze filtrują tę samą kolumnę o niskiej kardynalności, a liczba odrębnych wartości pozostaje w setkach, a nie w milionach
- Wiadro gdy użyteczna kolumna ma zbyt wiele odrębnych wartości, aby stanowić katalog, lub gdy tabela jest wielokrotnie dołączana lub próbkowana na podstawie tej kolumny
- Użyj obu w przypadku dużych tabel faktów: partycjonowanie według daty, a następnie tworzenie kontenera wewnątrz każdej partycji według klucza łączenia
Tryb awarii, na który należy zwrócić uwagę, to problem małych plików. Partycjonowanie kolumny o bardzo dużej kardynalności – znacznika czasu lub identyfikatora klienta – generuje tysiące maleńkich katalogów, z których każdy zawiera plik znacznie mniejszy niż rozmiar bloku HDFS. To zwiększa obciążenie pamięci NameNode i spowalnia każde skanowanie, a właśnie temu partycjonowanie wyników miało zapobiec. Podział na grupy pozwala tego uniknąć, ponieważ liczba plików jest ograniczona definicją tabeli.
Podział na przedziały ma swoje własne zastrzeżenie: układ jest poprawny tylko wtedy, gdy każdy zapisujący go przestrzega. Liczba przedziałów zadeklarowana podczas tworzenia tabeli to metadane, więc zadanie, które zapisuje dane do tabeli bez poprawnego klastrowania, może pozostawić pliki niezgodne z zadeklarowanym układem, a późniejsze próbkowanie lub łączenie przedziałów odczyta niewłaściwe wiersze.








