Jak dostroić numer wykonywacza spark, rdzenie i pamięć wykonywacza?

Od czego zacząć stroić wyżej wymienione paramy. Czy zaczynamy od pamięci executora i otrzymujemy liczbę executorów, czy zaczynamy od rdzeni i otrzymujemy numer executora. Podążałem za linkiem . Jednak mam pomysł na wysokim poziomie, ale nadal Nie wiem, jak i od czego zacząć i dojść do ostatecznego wniosku.

Author: Ramzy, 2016-06-17

2 answers

Następująca odpowiedź obejmuje 3 główne aspekty wymienione w tytule-ilość executorów, pamięć executora i ilość rdzeni. Mogą istnieć inne parametry, takie jak pamięć sterowników i inne, których nie adresowałem w tej odpowiedzi, ale chciałbym dodać w najbliższej przyszłości.

Case 1 Hardware-6 węzłów, a każdy węzeł 16 rdzeni, 64 GB RAM

Każdy executor jest instancją JVM. Możemy więc mieć wiele executorów w jednym węźle

Pierwszy 1 rdzeń i 1 GB jest potrzebny do System operacyjny i demony Hadoop, więc dostępne są 15 rdzeni, 63 GB PAMIĘCI RAM dla każdego węzła

zacznij od wyboru liczby rdzeni :

Number of cores = Concurrent tasks as executor can run 

So we might think, more concurrent tasks for each executor will give better performance. But research shows that
any application with more than 5 concurrent tasks, would lead to bad show. So stick this to 5.

This number came from the ability of executor and not from how many cores a system has. So the number 5 stays same
even if you have double(32) cores in the CPU.

liczba wykonawców:

Coming back to next step, with 5 as cores per executor, and 15 as total available cores in one Node(CPU) - we come to 
3 executors per node.

So with 6 nodes, and 3 executors per node - we get 18 executors. Out of 18 we need 1 executor (java process) for AM in YARN we get 17 executors

This 17 is the number we give to spark using --num-executors while running from spark-submit shell command

pamięć dla każdego executora:

From above step, we have 3 executors  per node. And available RAM is 63 GB

So memory for each executor is 63/3 = 21GB. 

However small overhead memory is also needed to determine the full memory request to YARN for each executor.
Formula for that over head is max(384, .07 * spark.executor.memory)

Calculating that overhead - .07 * 21 (Here 21 is calculated as above 63/3)
                            = 1.47

Since 1.47 GB > 384 MB, the over head is 1.47.
Take the above from each 21 above => 21 - 1.47 ~ 19 GB

So executor memory - 19 GB

Liczby końcowe-Executory - 17, Rdzenie 5, pamięć executora-19 GB


Case 2 Hardware : Same 6 Node, 32 rdzenie, 64 GB

5 to samo dla dobrego współbieżności

Liczba executorów dla każdego węzła = 32/5 ~ 6

Total executors = 6 * 6 węzłów = 36. Następnie liczba końcowa to 36-1 dla AM = 35

Pamięć executora to: 6 executorów dla każdego węzła. 63/6 ~ 10 . Over head jest .07 * 10 = 700 MB. Więc zaokrąglając do 1GB jak nad głową, otrzymujemy 10-1 = 9 GB

Liczby końcowe-Executory-35, Rdzenie 5, pamięć executora-9 GB


Przypadek 3

Powyższe scenariusze zaczynają się od przyjęcia liczby rdzeni jako stałej i przeniesienia do # executorów i pamięci.

Teraz dla pierwszy przypadek, jeśli uważamy, że nie potrzebujemy 19 GB, a tylko 10 GB jest wystarczające, to następujące liczby:

Rdzenie 5 # of executors for each node = 3

Na tym etapie doprowadziłoby to do 21, a następnie 19, zgodnie z naszymi pierwszymi obliczeniami. Ale ponieważ myśleliśmy, że 10 jest w porządku( Zakładamy małe koszty), to nie możemy przełączać # executorów na węzeł do 6 (Jak 63/10). Becase z 6 executorami na węzeł i 5 rdzeniami sprowadza się do 30 rdzeni na węzeł, gdy mamy tylko 16 rdzeni. Więc musimy również Zmień numer rdzenie dla każdego executora. / Align = "left" / ]}

Magiczna liczba 5 wynosi 3 (dowolna liczba mniejsza lub równa 5). Tak więc z 3 rdzeniami i 15 dostępnymi rdzeniami-dostajemy 5 executorów na węzeł. So (5 * 6 -1) = 29 executors

Więc pamięć wynosi 63/5 ~ 12. Over head to 12*.07=.84 Tak więc pamięć executora wynosi 12-1 GB = 11 GB

Ostateczne liczby to 29 executorów, 3 rdzenie, pamięć executora to 11 GB


dynamiczny Przydział:

Uwaga: górna granica dla liczby wykonawców, jeśli włączona jest dynamiczna alokacja. Mówi to, że aplikacja spark może w razie potrzeby zjeść wszystkie zasoby. Więc w klaster, w którym działają inne aplikacje, a także potrzebują rdzeni do uruchamiania zadań, upewnij się, że robisz to na poziomie klastra. Możesz przeznaczyć określona liczba rdzeni dla przędzy w oparciu o dostęp Użytkownika. Więc można utworzyć spark_user może być, a następnie dać rdzenie (min / max) dla tego użytkownika. Limity te dotyczą dzielenia się między spark i innymi aplikacjami, które działają na przędzy.

Iskra.dynamiczna alokacja.enabled-gdy jest ustawione na true-nie musimy wspominać o executorach. Powód jest poniżej:

Statyczny numer params, który podajemy w spark-submit, jest dla całego czasu trwania zadania. Jednak jeśli dynamiczna alokacja pojawi się w obrazie, będą różne etapy, takie jak

Od czego zacząć:

Początkowa liczba wykonawców (Iskra.dynamiczna alokacja.initialExecutors) na początek

Ile:

Następnie w oparciu o load (zadania oczekujące), ile żądać. W końcu będą to liczby, które dajemy w spark-submit w sposób statyczny. Więc po ustawieniu początkowych numerów executora przechodzimy na min (spark.dynamiczna alokacja.minExecutors ) i max (spark.dynamiczna alokacja.maxExecutors ) numbers.

Kiedy zapytać lub dać:

Kiedy request new executors (spark.dynamiczna alokacja.schedulerBacklogTimeout) - nie było zadań oczekujących na tak długi czas. więc Prośba. liczba wykonawców żądanych w każdej rundzie rośnie wykładniczo w stosunku do poprzedniej rundy. Na przykład aplikacja doda 1 executora w pierwszej rundzie, a następnie 2, 4, 8 i tak dalej executorów w kolejnych rundach. W określonym punkcie powyższy max pojawia się na obrazku

Kiedy oddajemy wykonawcę (Iskra.dynamiczna alokacja.executorIdleTimeout) -

Proszę mnie poprawić, jeśli coś przeoczyłem. Powyższe jest moim zrozumieniem opartym na blogu, który udostępniłem w pytaniu i niektórych zasobach internetowych. Dziękuję. ty.

Referencje:

 117
Author: Ramzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 12:36:06

Również, to zależy od Twojego przypadku użycia, ważnym parametrem konfiguracyjnym jest:

spark.memory.fraction(ułamek (przestrzeń sterty-300Mb) użytej do wykonania i Przechowywania) z http://spark.apache.org/docs/latest/configuration.html#memory-management .

Jeśli nie używasz Cache / persist, ustaw go na 0.1, więc masz całą pamięć dla swojego programu.

Jeśli używasz Cache/persist, możesz sprawdzić pamięć pobraną przez:

sc.getExecutorMemoryStatus.map(a => (a._2._1 - a._2._2)/(1024.0*1024*1024)).sum

Czy czytasz dane z HDFS czy z HTTP?

Znowu, a strojenie zależy od przypadku użycia.

 5
Author: Thomas Decaux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-07 10:46:17