W zależności od wersji Hive i konfiguracji, odpowiedź na pytanie może być różna. Byłoby łatwiej, gdybyś mógł udostępnić swoje dokładne zapytanie wraz z instrukcjami tworzenia dwóch tabel i oszacowaniem ich rozmiarów.
Aby lepiej zrozumieć problem, przejrzyjmy, jak działa "normalne" sprzężenie wewnętrzne w Hive.
Hive przyłączyć MapReduce:
Oto uproszczony opis sposobu sprzężenie wewnętrzne w Ulu zostanie skompilowany do MapReduce. W ogóle, jeśli masz dwie tabele t1 i t2 z kwerendy dołączyć jak:
SELECT
t1.key, t1.value, t2.value
FROM
t1
JOIN
t2 (ON t1.key = t2.key);
Gdzie T1 ma następującą zawartość:
k_1 v1_1
k_2 v1_2
k_3 v1_3
Gdzie, t2 ma następującą zawartość:
k_2 v2_2
k_3 v2_3
k_4 v2_4
oczekujemy, że wynik przyłączyć się
k_2 v1_2 v2_2
k_3 v1_3 v2_3
Zakładając, że tabele są przechowywane na HDFS, ich zawartość zostanie podzielona na Podziały plików. Program odwzorowujący podejmie plik podzielony jako dane wejściowe i wyemituje klucz jako kolumnę kluczową tabeli oraz wartość jako złożony z kolumny wartości tabeli i flagi (reprezentującej tabelę, z której pochodzi rekord tj. T1 lub t2) .
Dla T1:
k_1, <v1_1, t1>
k_2, <v1_2, t1>
k_3, <v1_3, t1>
Dla T2:
k_2, <v2_2, t2>
k_3, <v2_3, t2>
k_4, <v2_4, t2>
Teraz te emitowane z zapisów przejść przez fazę losowego gdzie wszystkie rekordy z tych samych kluczy są zgrupowane razem i wysłane do reduktor. Kontekst każdej operacji zmniejszania to jeden klucz i lista zawierająca wszystkie wartości odpowiadające temu kluczowi. W praktyce jeden reduktor wykonuje kilka operacji redukcji.
W powyższym przykładzie, chcemy uzyskać następujące ugrupowania:
k_1, <<v1_1, t1>>
k_2, <<v1_2, t1>, <v2_2, t2>>
k_3, <<v1_3, t1>, <v2_3, t2>>
k_4, <<v2_4, t2>>
Oto, co dzieje się w reduktorze. Dla każdej wartości na liście wartości reduktor wykona mnożenie, jeśli wartości odpowiadają różnym tabelom.
Dla k_1, nie ma wartości od t2 i nic nie jest emitowany.
Na k_2, mnożenie wartości emitowane - k_2, v1_2, v2_2 (ponieważ nie ma wartość z każdej tabeli 1x1 = 1)
Na k_3, mnożenie wartości emitowane - k_3, v1_3 , v2_3 (ponieważ nie ma wartość z każdej tabeli 1x1 = 1)
Na k_4 nie ma wartość od t1 i nic nie jest emitowany. Dzięki temu uzyskasz wynik, którego oczekiwałeś od swojego wewnętrznego połączenia.
Ok, więc co mam zrobić?
Możliwe, że dane są pochylone. Innymi słowy, gdy reduktor pobiera dane, lista wartości odpowiadająca pewnemu kluczowi jest bardzo długa, co powoduje błąd. Aby złagodzić problem, możesz spróbować zwiększyć pamięć dostępną dla maszyny JVM. Można to zrobić, ustawiając wartość mapred.child.java.opts
na wartość podobną do -Xmx512M
w pliku Hive-Site.xml. Możesz sprawdzić aktualną wartość tego parametru wykonując set mapred.child.java.opts;
w swojej powłoce Hive.
Można spróbować użyć alternatywy dla „regular” przyłączyć, na przykład dołączenie do mapy. Powyższe wyjaśnienie łączenia ma zastosowanie do regularnych połączeń, w których łączenie odbywa się w reduktorach. W zależności od wersji Hive, Hive może automatycznie przekonwertować zwykłe dołączenie do łączenia mapy, które jest szybsze (ponieważ dołączenie odbywa się w fazie mapy). Aby włączyć optymalizację, ustaw hive.auto.convert.join
na true
. Ten obiekt został wprowadzony w Hive 0.7
Oprócz ustawiania hive.auto.convert.join
do true
, można także ustawić hive.optimize.skewjoin
do true
. Spowoduje to zmianę ukośności w problemie z danymi opisanym w 1.
Hej, powinieneś "zaakceptować" odpowiedź Marka Grover'a, jeśli zgadzasz się z jego rozwiązaniem, zamiast akceptować własne rozwiązanie, które nie jest tak naprawdę rozwiązaniem, ale zrozumieniem poprawnej odpowiedzi. –
+1 w powyższym komentarzu. Ale myślę, że odkąd jest nowicjuszem w SO, mógł nie zdawać sobie sprawy, jak to działa. –