Wiem, że obie są wykonywane na kolumnie w tabeli, ale jak każda operacja jest inna.
Odpowiedzi:
Partycjonowanie danych jest często używane do poziomego rozkładania obciążenia, co ma korzystny wpływ na wydajność i pomaga w logicznej organizacji danych. Przykład : jeśli mamy do czynienia z dużą employee
tabelą i często uruchamiamy zapytania z WHERE
klauzulami, które ograniczają wyniki do konkretnego kraju lub działu. Aby uzyskać szybszą odpowiedź na zapytanie, tabela Hive może być PARTITIONED BY (country STRING, DEPT STRING)
. Tabele partycjonowania zmieniają strukturę magazynu danych, a Hive utworzy teraz podkatalogi odzwierciedlające strukturę partycjonowania, taką jak
... / workers / country = ABC / DEPT = XYZ .
Jeśli limit zapytań dla pracownika z country=ABC
, będzie skanował zawartość tylko jednego katalogu country=ABC
. Może to znacznie poprawić wydajność zapytań, ale tylko wtedy, gdy schemat partycjonowania odzwierciedla typowe filtrowanie. Funkcja partycjonowania jest bardzo przydatna w Hive, jednak projekt, który tworzy zbyt wiele partycji, może zoptymalizować niektóre zapytania, ale może być szkodliwy dla innych ważnych zapytań. Inną wadą jest posiadanie zbyt wielu partycji, to duża liczba plików i katalogów Hadoop, które są tworzone niepotrzebnie i stanowią obciążenie dla NameNode, ponieważ musi on przechowywać wszystkie metadane systemu plików w pamięci.
Bucketing to kolejna technika rozkładania zestawów danych na łatwiejsze do zarządzania części. Na przykład załóżmy, że tabela używająca date
partycji najwyższego poziomu i partycji employee_id
drugiego poziomu prowadzi do zbyt wielu małych partycji. Zamiast tego, jeśli podzielimy tabelę pracowników i użyjemy jej employee_id
jako kolumny do grupowania, wartość tej kolumny zostanie zaszyfrowana przez liczbę zdefiniowaną przez użytkownika do segmentów. Rekordy z tym samym employee_id
będą zawsze przechowywane w tym samym zasobniku. Zakładając, że liczba employee_id
jest znacznie większa niż liczba koszy, każdy z nich będzie miał wiele employee_id
. Tworząc tabelę możesz określić jakCLUSTERED BY (employee_id) INTO XX BUCKETS;
gdzie XX to liczba segmentów. Bucketing ma kilka zalet. Liczba segmentów jest stała, więc nie zmienia się wraz z danymi. Jeśli dwie tabele są podzielone według employee_id
, Hive może utworzyć logicznie poprawne próbkowanie. Bucketing pomaga również w wydajnym łączeniu po stronie mapy itp.
W poprzednich wyjaśnieniach brakuje kilku szczegółów. Aby lepiej zrozumieć, jak działa partycjonowanie i grupowanie, należy przyjrzeć się, jak dane są przechowywane w gałęzi. Powiedzmy, że masz stolik
CREATE TABLE mytable (
name string,
city string,
employee_id int )
PARTITIONED BY (year STRING, month STRING, day STRING)
CLUSTERED BY (employee_id) INTO 256 BUCKETS
wtedy gałąź będzie przechowywać dane w hierarchii katalogów, takiej jak
/user/hive/warehouse/mytable/y=2015/m=12/d=02
Musisz więc zachować ostrożność podczas partycjonowania, ponieważ jeśli na przykład podzielisz na partycje według identyfikatora pracownika i masz miliony pracowników, w końcu będziesz mieć miliony katalogów w swoim systemie plików. Termin „ liczność ” odnosi się do liczby możliwych wartości, jakie może mieć pole. Na przykład, jeśli masz pole „kraj”, krajów na świecie jest około 300, więc liczność będzie wynosić ~ 300. W przypadku pola takiego jak „timestamp_ms”, które zmienia się co milisekundę, liczność może wynosić miliardy. Ogólnie rzecz biorąc, wybierając pole do partycjonowania, nie powinno ono mieć wysokiej liczności, ponieważ w systemie plików będzie o wiele za dużo katalogów.
Z drugiej strony grupowanie, czyli segmentowanie, da stałą liczbę plików, ponieważ określa się liczbę segmentów. To, co zrobi, to zajmie pole, obliczy hash i przypisze rekord do tego zasobnika. Ale co się stanie, jeśli użyjesz, powiedzmy, 256 segmentów, a pole, na którym się znajdujesz, ma niską liczność (na przykład jest to stan USA, więc może być tylko 50 różnych wartości)? Będziesz mieć 50 zasobników z danymi i 206 zasobników bez danych.
Ktoś już wspomniał, jak partycje mogą radykalnie zmniejszyć ilość zapytanych danych. Tak więc w mojej przykładowej tabeli, jeśli chcesz wykonywać zapytania tylko od określonej daty do przodu, partycjonowanie według roku / miesiąca / dnia radykalnie zmniejszy ilość operacji we / wy. Myślę, że ktoś wspomniał również o tym, jak bucketing może przyspieszyć łączenie z innymi tabelami, które mają dokładnie takie same przedziały , więc w moim przykładzie, jeśli łączysz dwie tabele na tym samym identyfikatorze pracownika, ul może wykonać łączenie segmentu po wiadrze (jeszcze lepiej jeśli są już posortowane według identyfikatora pracownika, ponieważ ma zamiar scalić części, które są już posortowane, co działa w czasie liniowym aka O (n)).
Tak więc segmentowanie działa dobrze, gdy pole ma wysoką kardynalność, a dane są równomiernie rozmieszczone w zasobnikach. Partycjonowanie działa najlepiej, gdy liczność pola partycjonowania nie jest zbyt wysoka.
Ponadto, można podzielić na wielu polach , z rozkazem (rok / miesiąc / dzień jest dobrym przykładem), natomiast można wiadro na tylko jedno pole .
Myślę, że spóźniłem się z odpowiedzią na to pytanie, ale ciągle pojawia się ono w moim kanale.
Navneet udzielił doskonałej odpowiedzi. Dodając do tego wizualnie.
Partycjonowanie pomaga w eliminacji danych, jeśli jest używane w klauzuli WHERE, gdzie grupowanie pomaga w organizowaniu danych z każdej partycji w wiele plików, tak aby ten sam zestaw danych był zawsze zapisywany w tym samym zasobniku. Bardzo pomaga w łączeniu kolumn.
Załóżmy, że masz tabelę z pięcioma kolumnami: nazwa, data_serwera, jakaś_kol3, jakaś_kol4 i jakaś_kol5. Załóżmy, że podzieliłeś tabelę na serwer_data i podzieliłeś na kolumnę z nazwą w 10 segmentach , struktura plików będzie wyglądać mniej więcej tak, jak poniżej.
Tutaj server_date = xyz to partycja, a 000 plików to pojemniki na każdej partycji. Zasobniki są obliczane na podstawie niektórych funkcji skrótu, więc wiersze o nazwie = Sandy zawsze będą znajdować się w tym samym zasobniku.
Partycjonowanie ula:
Partycja dzieli duże ilości danych na wiele wycinków w oparciu o wartość kolumny (kolumn) tabeli.
Załóżmy, że przechowujesz informacje o ludziach z całego świata w ponad 196 krajach, obejmujących około 500 milionów wpisów. Jeśli chcesz zapytać osoby z określonego kraju (Watykanu), w przypadku braku podziału na partycje, musisz przeskanować wszystkie 500 milionów wpisów, aby pobrać nawet tysiące wpisów z danego kraju. Jeśli podzielisz tabelę na partycje według kraju, możesz dostroić proces zapytań, po prostu sprawdzając dane tylko dla jednej partycji krajowej. Partycja Hive tworzy oddzielny katalog dla wartości kolumn.
Plusy:
Cons:
Wiaderko ula:
Bucketing rozkłada dane na łatwiejsze do zarządzania lub równe części.
Dzięki partycjonowaniu istnieje możliwość tworzenia wielu małych partycji na podstawie wartości kolumn. Jeśli zdecydujesz się na segmentowanie, ograniczasz liczbę segmentów do przechowywania danych. Liczba ta jest definiowana podczas skryptów tworzenia tabel.
Plusy
Cons
Zanim przejdziemy do tego Bucketing
, musimy zrozumieć, co Partitioning
to jest. Weźmy jako przykład poniższą tabelę. Zauważ, że w poniższym przykładzie podałem tylko 12 rekordów dla zrozumienia poziomu początkującego. W scenariuszach czasu rzeczywistego możesz mieć miliony rekordów.
PARTYCJONOWANIE
---------------------
Partitioning
służy do uzyskania wydajności podczas wykonywania zapytań dotyczących danych. Na przykład w powyższej tabeli, jeśli napiszemy poniższy sql, należy przeskanować wszystkie rekordy w tabeli, co zmniejsza wydajność i zwiększa narzut.
select * from sales_table where product_id='P1'
Aby uniknąć pełnego skanowania tabeli i czytać tylko rekordy z nim związane product_id='P1'
, możemy podzielić (podzielić pliki tabeli gałęzi) na wiele plików na podstawie product_id
kolumny. W ten sposób plik tabeli gałęzi zostanie podzielony na dwa pliki, jeden zi product_id='P1'
drugi z product_id='P2'
. Teraz, gdy wykonamy powyższe zapytanie, przeskanuje ono tylko product_id='P1'
plik.
../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2
Składnia tworzenia partycji jest podana poniżej. Zauważ, że nie powinniśmy używać product_id
definicji kolumny razem z niepartycjonowanymi kolumnami w poniższej składni. Powinno to być tylko w partitioned by
klauzuli.
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10))
Wady : Podczas partycjonowania powinniśmy być bardzo ostrożni. Oznacza to, że nie należy go używać w przypadku kolumn, w których liczba powtarzających się wartości jest bardzo mniejsza (szczególnie w kolumnach klucza podstawowego), ponieważ zwiększa liczbę partycjonowanych plików i zwiększa obciążenie dla Name node
.
BUCKETING
------------------
Bucketing
służy do przezwyciężenia tego cons
, o czym wspomniałem w sekcji o partycjonowaniu. Powinno to być używane, gdy w kolumnie jest bardzo mało powtarzających się wartości (przykład - kolumna klucza podstawowego). Jest to podobne do koncepcji indeksu w kolumnie klucza podstawowego w RDBMS. W naszej tabeli możemy wziąć Sales_Id
kolumnę do wiaderkowania. Przyda się, gdy będziemy musieli odpytać sales_id
kolumnę.
Poniżej znajduje się składnia segmentowania.
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10)) Clustered by(Sales_Id) into 3 buckets
Tutaj dalej podzielimy dane na kilka dodatkowych plików na partycjach.
Ponieważ określiliśmy 3
zasobniki, jest on podzielony na 3 pliki dla każdego product_id
. Używa go wewnętrznie modulo operator
do określenia, w którym wiadrze każdy sales_id
powinien być przechowywany. Na przykład, dla product_id='P1'
, sales_id=1
będzie przechowywany w pliku 000001_0 (tj. 1% 3 = 1), sales_id=2
będzie przechowywany w pliku 000002_0 (tj. 2% 3 = 2), sales_id=3
będzie przechowywany w pliku 000000_0 (tj. 3% 3 = 0) itd.
hashCode()
z ciągu jako funkcji skrótu? Czy programista może wybrać funkcję skrótu?
Różnica polega na tym, że dzielenie grupuje pliki według nazwy kolumny, a partycjonowanie dzieli pliki według określonej wartości w tabeli
Mam nadzieję, że poprawnie to zdefiniowałem
Tutaj są świetne odpowiedzi. Chciałbym, żeby było to krótkie, aby zapamiętać różnicę między partycjami a zasobnikami.
Zwykle partycjonujesz na mniej unikalnej kolumnie. I łyżką na najbardziej unikalnej kolumnie.
Przykład, jeśli weźmiesz pod uwagę populację świata z krajem, imieniem i nazwiskiem osoby i jej identyfikatorem biometrycznym jako przykładem. Jak możesz się domyślić, pole kraju byłoby mniej unikalną kolumną, a identyfikator biometryczny byłby najbardziej unikalną kolumną. Idealnie byłoby więc podzielić tabelę według kraju i podzielić ją według identyfikatora biometrycznego.
Używanie partycji w tabeli Hive jest wysoce zalecane z poniższego powodu -
Przykład: -
Załóżmy, że plik wejściowy (100 GB) jest ładowany do tabeli temp-hive-table i zawiera dane bankowe z różnych regionów geograficznych.
Tabela ula bez partycji
Insert into Hive table Select * from temp-hive-table
/hive-table-path/part-00000-1 (part size ~ hdfs block size)
/hive-table-path/part-00000-2
....
/hive-table-path/part-00000-n
Problem z tym podejściem polega na tym, że skanuje całe dane w poszukiwaniu dowolnego zapytania uruchomionego w tej tabeli. Czas odpowiedzi będzie długi w porównaniu z innymi podejściami, w których używane są partycjonowanie i Bucketing.
Stół ula z przegrodą
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 10 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 20 GB)
....
/hive-table-path/country=UK/part-00000-n (file size ~ 5 GB)
Zalety - tutaj można uzyskać szybszy dostęp do danych, jeśli chodzi o przeszukiwanie danych dla określonych transakcji geograficznych. Wady - Wstawianie / wysyłanie zapytań do danych można dodatkowo ulepszyć, dzieląc dane w każdej partycji. Zobacz opcję Bucketing poniżej.
Tabela ula z partycjami i zasobnikami
Uwaga: Utwórz tabelę gałęzi… z „CLUSTERED BY (Partiton_Column) w 5 zasobnikach
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-2 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-3 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-4 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-5 (file size ~ 2 GB)
/hive-table-path/country=Canada/part-00000-1 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-3 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-4 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-5 (file size ~ 4 GB)
....
/hive-table-path/country=UK/part-00000-1 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-2 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-3 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-4 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-5 (file size ~ 1 GB)
Zalety - szybsze wstawianie. Szybsze zapytanie.
Wady - Bucketing spowoduje utworzenie większej liczby plików. W niektórych przypadkach może wystąpić problem z wieloma małymi plikami
Mam nadzieję, że to pomoże !!