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.

  • 🗂️. Partycja jest katalogiem: Każda odrębna wartość klucza partycji staje się osobnym podkatalogiem w folderze tabeli w systemie HDFS.
  • ✂️. Przycinanie partycji: Zapytanie filtrujące według klucza partycji odczytuje tylko pasujące katalogi zamiast skanować całą tabelę.
  • ⚙️ Wymagany tryb dynamiczny: Aby załadować wiele partycji za pomocą polecenia SELECT, hive.exec.dynamic.partition.mode musi być ustawione na nonstrict.
  • 🧮 Wiadro jest plikiem: CLUSTERED BY haszuje wybraną kolumnę i zapisuje każdy wiersz do jednego ze stałej liczby plików.
  • 🔍 Próbkowanie i łączenie: Tabele kontenerowe obsługują wydajne odczyty TABLESAMPLE i łączenia kontenerów po stronie mapy, czego nie potrafią zrobić zwykłe tabele.
  • 📐 Wybierz według kardynalności: Partycjonowanie według kolumn o niskiej kardynalności, takich jak stan lub data, oraz kolumn o wysokiej kardynalności, takich jak identyfikatory użytkowników.

Wyjaśnienie partycji i kontenerów Hive na przykładzie rozwiązania

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.

  1. Tworzenie tabeli allstates
    create table allstates(state string, District string,Enrolments string)
    
    row format delimited
    
    fields terminated by ',';
    
  2. Ładowanie danych do utworzonej tabeli allstates
    Load data local inpath '/home/hduser/Desktop/AllStates.csv' into table allstates;
  3. Utworzenie tablicy partycji
    create table state_part(District string,Enrolments string) PARTITIONED BY(state string);
  4. W przypadku partycji musimy ustawić tę właściwość
    set hive.exec.dynamic.partition.mode=nonstrict
  5. Ładowanie danych do tablicy partycji
    INSERT OVERWRITE TABLE state_part PARTITION(state)
    SELECT district,enrolments,state from  allstates;
  6. 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.

Powłoka Hive tworzy tabelę allstates z trzema rozdzielonymi kolumnami

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.

Ładowanie pliku AllStates.csv do allstates i tworzenie partycjonowanej tabeli state_part

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.

Wyjście zadania MapReduce ładuje jedną partycję Hive na wartość stanu

Wyświetlenie katalogu magazynu w systemie HDFS potwierdza wynik kroku 6 – powłoka raportuje 38 pozycji, jedną część_stanu/stan= katalog według stanu.

Lista HDFS pokazująca 38 katalogów partycji state_part w magazynie Hive

Na podstawie powyższego kodu wykonujemy następujące czynności

  1. Utworzenie tabeli allstates z 3 nazwami kolumn, takimi jak stan, okręg i zapisy
  2. Ładowanie danych do tabeli allstates
  3. Utworzenie tablicy partycji ze stanem jako kluczem partycji
  4. W tym kroku ustaw tryb partycjonowania na nieścisły (ten tryb aktywuje dynamiczny tryb partycjonowania)
  5. Ładowanie danych do tabeli partycji state_part
  6. Rzeczywiste przetwarzanie i tworzenie tablic partycji na podstawie stanu jako klucza partycji
  7. 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.

Polecenie CREATE TABLE w Hive grupujące samplebucket w cztery kontenery

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.

Polecenie INSERT OVERWRITE kopiujące wiersze pracowników do tabeli samplebucket

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.

Lista czterech plików kontenera utworzonych w katalogu samplebucket w systemie HDFS

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.

FAQ

Uruchom polecenie SHOW PARTITIONS table_name w powłoce Hive. Odczytuje ono metadane i wyświetla jeden wiersz dla każdego katalogu partycji, co jest szybsze niż wyświetlanie ścieżki magazynu w systemie HDFS, a także potwierdza synchronizację metadanych.

ALTER TABLE table_name ADD PARTITION (state='Goa') rejestruje nowy katalog, a ALTER TABLE table_name DROP PARTITION (state='Goa') usuwa go. Usuńping zarządzana partycja usuwa swoje dane, podczas gdy upuszczanieping zewnętrzny czyści tylko wpis metamagazynu.

Hive domyślnie ogranicza liczbę partycji dynamicznych do 100 na węzeł i 1000 na instrukcję. Klucz z bardziej wyraźnymi wartościami przekracza limit i przerywa zadanie. Zwiększ wartość hive.exec.max.dynamic.partitions.pernode i hive.exec.max.dynamic.partitions lub wybierz klucz o mniejszej wartości.

Nie. Było to potrzebne w Hive 0.x i 1.x, aby wymusić dopasowanie liczby reduktorów do liczby kontenerów. HIVE-12331 usunęło to w Hive 2.0, a silnik teraz pobiera zarówno liczbę reduktorów, jak i kolumnę klastra z tabeli.

Funkcja TABLESAMPLE(BUCKET x OUT OF y ON column) odczytuje tylko pasujące pliki kontenera zamiast skanować wszystkie. Ponieważ wiersze były haszowane w tej samej kolumnie w momencie zapisu, próbka jest powtarzalna i znacznie tańsza niż filtr losowych wierszy.

Podzielenie tabeli na tysiące małych plików marnuje pamięć NameNode i uruchamia jedno zadanie na plik, przez co skanowanie jest wolniejsze. Zazwyczaj następuje to po kluczu partycji o bardzo dużej kardynalności. Klucze o mniejszej liczbie kluczy, grupowanie lub kompresja plików rozwiązują ten problem.

Tak. Analiza logów zapytań i modele uczenia maszynowego w narzędziach takich jak Cloudera Workload XM klasyfikują kolumny według częstotliwości filtrowania, asymetrii i kardynalności, a następnie sugerują układ. Sugestia nadal wymaga weryfikacji, ponieważ nie widzi zaplanowanych obciążeń.

Drugi pilot szybko tworzy instrukcje PARTITIONED BY i CLUSTERED BY na podstawie komentarza, a asystenci agenta mogą generować skrypt dla całego obciążenia. Zawsze sprawdzaj wygenerowaną liczbę kontenerów i klucz pod kątem rzeczywistej kardynalności, ponieważ model zgaduje wyłącznie na podstawie nazw.

Podsumuj ten post następująco: