Próbuję zrozumieć związek między liczbą rdzeni i liczbą wykonawców podczas uruchamiania zadania Spark w YARN.
Środowisko testowe wygląda następująco:
- Liczba węzłów danych: 3
- Specyfikacja maszyny węzła danych:
- Procesor: Core i7-4790 (liczba rdzeni: 4, liczba wątków: 8)
- RAM: 32 GB (8 GB x 4)
- HDD: 8 TB (2 TB x 4)
Sieć: 1 Gb
Wersja Spark: 1.0.0
Wersja Hadoop: 2.4.0 (Hortonworks HDP 2.1)
Przepływ pracy Spark: sc.textFile -> filtr -> mapa -> filtr -> mapToPair -> zmniejszByKey -> mapa -> saveAsTextFile
Dane wejściowe
- Wpisz: pojedynczy plik tekstowy
- Rozmiar: 165 GB
- Liczba linii: 454,568,833
Wynik
- Liczba linii po drugim filtrze: 310,640,717
- Liczba linii pliku wynikowego: 99,848,268
- Rozmiar pliku wynikowego: 41 GB
Zadanie zostało uruchomione z następującymi konfiguracjami:
--master yarn-client --executor-memory 19G --executor-cores 7 --num-executors 3
(executory na węzeł danych, użyj tyle co rdzenie)--master yarn-client --executor-memory 19G --executor-cores 4 --num-executors 3
(liczba rdzeni zredukowana)--master yarn-client --executor-memory 4G --executor-cores 2 --num-executors 12
(mniej rdzenia, więcej executora)
Czasy, które upłynęły:
50 min 15 sek
55 min 48 sek
31 min 23 sek
Ku mojemu zaskoczeniu (3) było znacznie szybsze.
Myślałem, że (1) będzie szybszy, ponieważ podczas tasowania komunikacja między wykonawcami będzie mniejsza.
Chociaż liczba rdzeni z (1) jest mniejsza niż (3), liczba rdzeni nie jest kluczowym czynnikiem, ponieważ 2) działała dobrze.
(Dodano odpowiedzi po odpowiedzi pwilmot.)
Aby uzyskać informacje, zrzut ekranu monitora wydajności wygląda następująco:
- Podsumowanie węzła danych Ganglia dla (1) - zadanie rozpoczęto o 04:37.
- Podsumowanie węzła danych Ganglia dla (3) - zadanie rozpoczęto o 19:47. Zignoruj wykres przed tym czasem.
Wykres z grubsza dzieli się na 2 sekcje:
- Po pierwsze: od początku do zmniejszenia Klucz: intensywny procesor, brak aktywności sieciowej
- Po drugie: po zmniejszeniu Klucz: obniżenie procesora, sieciowe operacje we / wy są gotowe.
Jak pokazuje wykres, (1) może zużywać tyle mocy procesora, ile zostało podane. Może to nie być problem z liczbą wątków.
Jak wytłumaczyć ten wynik?
źródło
Odpowiedzi:
Wyjaśnienie zostało podane w artykule na blogu Cloudera, How-to: Tune Your Apache Spark Jobs (Part 2) .
źródło
yarn.scheduler.capacity.resource-calculator
wyłączonej, która jest domyślna. Dzieje się tak, ponieważ domyślnie programuje według pamięci, a nie procesora.Według Sandy Ryza , gdy uruchamiasz swoją aplikację Spark na HDFS
Uważam więc, że twoja pierwsza konfiguracja jest wolniejsza niż trzecia z powodu złej przepustowości we / wy HDFS
źródło
Nie grałem sam z tymi ustawieniami, więc to tylko spekulacje, ale jeśli myślimy o tym problemie jako o normalnych rdzeniach i wątkach w systemie rozproszonym, to w klastrze możesz użyć do 12 rdzeni (4 * 3 maszyn) i 24 wątków (8 * 3 maszyny). W pierwszych dwóch przykładach podajesz zadaniu sporo rdzeni (potencjalna przestrzeń obliczeniowa), ale liczba wątków (zadań) do uruchomienia na tych rdzeniach jest tak ograniczona, że nie jesteś w stanie zużyć dużej ilości przydzielonej mocy obliczeniowej dlatego zadanie jest wolniejsze, mimo że przydzielono więcej zasobów obliczeniowych.
wspominasz, że twoja troska była na etapie tasowania - chociaż miło jest ograniczyć obciążenie ogólne na etapie tasowania, o wiele ważniejsze jest wykorzystanie równoległości klastra. Pomyśl o ekstremalnym przypadku - pojedynczym wątku z zerowym tasowaniem.
źródło
Myślę, że odpowiedź tutaj może być nieco prostsza niż niektóre zalecenia tutaj.
Wskazówką jest dla mnie wykres sieci klastrów. Dla przebiegu 1 wykorzystanie jest stałe przy ~ 50 M bajtów / s. Dla przebiegu 3 stałe wykorzystanie jest podwojone, około 100 M bajtów / s.
Z postu na blogu cloudera udostępnionego przez DzOrd można zobaczyć ten ważny cytat:
Zróbmy więc kilka obliczeń, aby zobaczyć, jakiej wydajności oczekujemy, jeśli to prawda.
Uruchom 1:19 GB, 7 rdzeni, 3 moduły wykonawcze
Uruchom 3: 4 GB, 2 rdzenie, 12 modułów wykonawczych
Jeśli zadanie jest w 100% ograniczone współbieżnością (liczbą wątków). Spodziewalibyśmy się, że środowisko wykonawcze będzie doskonale odwrotnie skorelowane z liczbą wątków.
Tak
ratio_num_threads ~= inv_ratio_runtime
, i wygląda na to, jesteśmy Network Limited.Ten sam efekt wyjaśnia różnicę między Run 1 a Run 2.
Uruchom 2:19 GB, 4 rdzenie, 3 executory
Porównanie liczby efektywnych wątków i środowiska wykonawczego:
To nie jest tak doskonałe jak poprzednie porównanie, ale nadal widzimy podobny spadek wydajności, gdy tracimy wątki.
Teraz ostatni raz: dlaczego tak jest, że uzyskujemy lepszą wydajność przy większej liczbie wątków, szczególnie. więcej wątków niż liczba procesorów?
Dobre wyjaśnienie różnicy między paralelizmem (tym, co otrzymujemy dzieląc dane na wiele procesorów) a współbieżnością (tym, co otrzymujemy, gdy używamy wielu wątków do pracy na jednym procesorze) jest zawarte w tym świetnym poście Rob Pike: Concurrency nie jest paralelizmem .
Krótkie wyjaśnienie jest takie, że jeśli zadanie Spark wchodzi w interakcję z systemem plików lub siecią, procesor spędza dużo czasu czekając na komunikację z tymi interfejsami i nie spędzając dużo czasu na „pracy”. Przydzielając tym procesorom więcej niż 1 zadanie do pracy na raz, spędzają mniej czasu na czekaniu, a więcej na pracy, a Ty widzisz lepszą wydajność.
źródło
Z doskonałych zasobów dostępnych na stronie pakietu Sparklyr RStudio :
źródło
Spark Dynamiczny przydział zapewnia elastyczność i dynamicznie przydziela zasoby. W tej liczbie minimalnych i maksymalnych wykonawców można podać. Można również podać liczbę programów wykonawczych, które należy uruchomić na początku aplikacji.
Przeczytaj poniżej o tym samym:
źródło
Myślę, że w pierwszych dwóch konfiguracjach jest mały problem. Pojęcia dotyczące wątków i rdzeni są następujące. Koncepcja wątków polega na tym, że jeśli rdzenie są idealne, użyj tego rdzenia do przetworzenia danych. Tak więc pamięć nie jest w pełni wykorzystana w pierwszych dwóch przypadkach. Jeśli chcesz porównać ten przykład, wybierz maszyny, które mają więcej niż 10 rdzeni na każdej maszynie. Następnie zrób ślad.
Ale nie dawaj więcej niż 5 rdzeni na executora, to będzie szyjka butelki na wydajności we / wy.
Tak więc najlepszymi maszynami do wykonania tego oznaczenia mogą być węzły danych, które mają 10 rdzeni.
Specyfikacja maszyny węzła danych: CPU: Core i7-4790 (liczba rdzeni: 10, liczba wątków: 20) RAM: 32 GB (8 GB x 4) HDD: 8 TB (2 TB x 4)
źródło
Myślę, że jednym z głównych powodów jest lokalizacja. Rozmiar pliku wejściowego to 165G, bloki pokrewne pliku z pewnością są rozproszone w wielu węzłach DataNodes, więcej wykonawców może uniknąć kopiowania sieciowego.
Spróbuj ustawić liczbę wykonawców równą liczbę bloków, myślę, że może być szybszy.
źródło