Mój klaster: 1 master, 11 slave, każdy węzeł ma 6 GB pamięci.
Moje ustawienia:
spark.executor.memory=4g, Dspark.akka.frameSize=512
Oto problem:
Najpierw odczytałem niektóre dane (2,19 GB) z HDFS na RDD:
val imageBundleRDD = sc.newAPIHadoopFile(...)
Po drugie , zrób coś na tym RDD:
val res = imageBundleRDD.map(data => {
val desPoints = threeDReconstruction(data._2, bg)
(data._1, desPoints)
})
Wreszcie , wyjście do HDFS:
res.saveAsNewAPIHadoopFile(...)
Po uruchomieniu mojego programu pokazuje:
.....
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:24 as TID 33 on executor 9: Salve7.Hadoop (NODE_LOCAL)
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:24 as 30618515 bytes in 210 ms
14/01/15 21:42:27 INFO cluster.ClusterTaskSetManager: Starting task 1.0:36 as TID 34 on executor 2: Salve11.Hadoop (NODE_LOCAL)
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Serialized task 1.0:36 as 30618515 bytes in 449 ms
14/01/15 21:42:28 INFO cluster.ClusterTaskSetManager: Starting task 1.0:32 as TID 35 on executor 7: Salve4.Hadoop (NODE_LOCAL)
Uncaught error from thread [spark-akka.actor.default-dispatcher-3] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[spark]
java.lang.OutOfMemoryError: Java heap space
Jest zbyt wiele zadań?
PS : Wszystko jest w porządku, gdy dane wejściowe wynoszą około 225 MB.
Jak mogę rozwiązać ten problem?
out-of-memory
apache-spark
hequn8128
źródło
źródło
Odpowiedzi:
Mam kilka sugestii:
spark.executor.memory=6g
. Upewnij się, że używasz jak największej ilości pamięci , sprawdzając interfejs użytkownika (pokaże, ile pamięci używasz)spark.storage.memoryFraction
. Jeśli nie używaszcache()
lub nie wpisujeszpersist
w swoim kodzie, może to również wynosić 0. Domyślnie jest to 0,6, co oznacza, że masz tylko 0,4 * 4 g pamięci na stos. Zmniejszenie IME frac często powoduje, że OOM znikają. AKTUALIZACJA: Od Spark 1.6 najwyraźniej nie będziemy już musieli bawić się tymi wartościami, Spark określi je automatycznie.String
i mocno zagnieżdżone struktury (takie jakMap
i zagnieżdżone klasy przypadków). Jeśli to możliwe, staraj się używać tylko typów pierwotnych i indeksować wszystkie elementy inne niż pierwotne, zwłaszcza jeśli oczekujesz wielu duplikatów. Jeśli to możliwe, wybierajWrappedArray
struktury zagnieżdżone. Lub nawet wdrożyć własną serializację - TY będziesz miał najwięcej informacji na temat efektywnego tworzenia kopii zapasowych danych w bajtach, UŻYJ IT !Dataset
do buforowania struktury, ponieważ będzie ona używać bardziej wydajnej serializacji. Powinno to być traktowane jako hack w porównaniu z poprzednim punktem. Budowanie wiedzy o domenie w algo / serializacji może zminimalizować pamięć / pamięć podręczną o 100x lub 1000x, podczas gdy wszystko,Dataset
co prawdopodobnie da, to 2x - 5x w pamięci i 10x skompresowany (parkiet) na dysku.http://spark.apache.org/docs/1.2.1/configuration.html
EDYCJA: (Więc mogę łatwiej wyszukiwać w Google) Następujące objawy wskazują również na ten problem:
źródło
spark.executor.memory
ponieważ zdecydowanie potrzebujesz pewnej ilości pamięci narzut we / wy. Jeśli użyjesz tego wszystkiego, spowolni Twój program. Wyjątkiem może być Unix, w którym to przypadku masz miejsce wymiany.Aby dodać do tego przypadek użycia, który często nie jest omawiany, przedstawię rozwiązanie przy składaniu
Spark
wnioskuspark-submit
w trybie lokalnym .Według gitbook Mastering Apache Spark przez Jacka Laskowskiego :
Zatem jeśli doświadczasz
OOM
błędy wheap
, wystarczy dostosowaćdriver-memory
raczej niżexecutor-memory
.Oto przykład:
źródło
Powinieneś skonfigurować ustawienia pamięci offHeap, jak pokazano poniżej:
Podaj pamięć sterownika i pamięć executora zgodnie z dostępnością pamięci RAM twoich maszyn. Możesz zwiększyć rozmiar offHeap, jeśli nadal masz problem z OutofMemory .
źródło
config
rozwiązało problem.Powinieneś zwiększyć pamięć sterownika. Myślę, że w folderze $ SPARK_HOME / conf powinieneś znaleźć plik
spark-defaults.conf
, edytować i ustawićspark.driver.memory 4000m
zależnie od pamięci w twoim systemie głównym. To właśnie naprawiło problem i wszystko działa płynnieźródło
Spójrz na skrypty startowe, w których ustawiony jest rozmiar sterty Java, wygląda na to, że nie ustawiasz tego przed uruchomieniem robota Spark.
Dokumentację do wdrażania skryptów można znaleźć tutaj .
źródło
start up scripts
Niestety treść skryptu, do którego prowadzi link, uległa zmianie. Nie ma takich opcji na dzień 19.12.2019Bardzo cierpiałem z powodu tego problemu, używamy dynamicznej alokacji zasobów i myślałem, że wykorzysta zasoby mojego klastra, aby jak najlepiej dopasować aplikację.
Ale prawda jest taka, że dynamiczny przydział zasobów nie ustawia pamięci sterownika i utrzymuje jej domyślną wartość 1 g.
Rozwiązałem go, ustawiając spark.driver.memory na liczbę odpowiadającą pamięci mojego sterownika (dla pamięci RAM 32 GB ustawiłem go na 18 GB)
możesz to ustawić za pomocą polecenia Spark Prześlij w następujący sposób:
Bardzo ważna uwaga, ta właściwość nie będzie brana pod uwagę, jeśli ustawisz ją z kodu, zgodnie z dokumentacją Spark:
źródło
Mówiąc ogólnie, pamięć Spark JVM Executora można podzielić na dwie części. Pamięć Spark i pamięć użytkownika. Jest to kontrolowane przez właściwość
spark.memory.fraction
- wartość wynosi od 0 do 1. Pracując z obrazami lub wykonując intensywne przetwarzanie pamięci w aplikacjach iskrowych, rozważ zmniejszeniespark.memory.fraction
. Dzięki temu więcej pamięci będzie dostępne do pracy aplikacji. Spark może się rozlać, więc nadal będzie działał z mniejszym udziałem pamięci.Druga część problemu to podział pracy. Jeśli to możliwe, podziel dane na mniejsze części. Mniejsze dane mogą wymagać mniej pamięci. Ale jeśli nie jest to możliwe, poświęcasz obliczenia pamięci. Zazwyczaj pojedynczy moduł wykonujący będzie obsługiwał wiele rdzeni. Całkowita pamięć modułów wykonawczych musi wystarczyć do obsługi wymagań dotyczących pamięci dla wszystkich współbieżnych zadań. Jeśli zwiększenie pamięci modułu wykonującego nie jest możliwe, można zmniejszyć liczbę rdzeni na moduł wykonujący, aby każde zadanie otrzymywało więcej pamięci do pracy. Przetestuj z 1 rdzeniowymi programami wykonawczymi, które mają największą możliwą pamięć, którą możesz dać, a następnie zwiększaj liczbę rdzeni, aż znajdziesz najlepszą liczbę rdzeni.
źródło
Zrzuciłeś główny log gc? Więc spotkałem podobny problem i znalazłem, że SPARK_DRIVER_MEMORY ustawia tylko stertę Xmx. Początkowy rozmiar stosu pozostaje 1G, a rozmiar stosu nigdy nie jest skalowany do sterty Xmx.
Przekazywanie „--conf” spark.driver.extraJavaOptions = -Xms20g ”rozwiązuje mój problem.
ps aux | grep java, a zobaczysz następujący dziennik: =
24501 30,7 1,7 41782944 2318184 pkt / 0 Sl + 18:49 0:33 / usr / java / latest / bin / java -cp / opt / spark / conf /: / opt / spark / jars / * -Xmx30g -Xms20g
źródło
Miejsce ustawienia wielkości sterty pamięci (przynajmniej w wersji Spark 1.0.0) znajduje się w conf / spark-env. Odpowiednimi zmiennymi są
SPARK_EXECUTOR_MEMORY
&SPARK_DRIVER_MEMORY
. Więcej dokumentów znajduje się w przewodniku wdrażaniaNie zapomnij również skopiować pliku konfiguracyjnego do wszystkich węzłów podrzędnych.
źródło
SPARK_EXECUTOR_MEMORY
&SPARK_DRIVER_MEMORY
?SPARK_EXECUTOR_MEMORY
, a jaki błąd kazałby ci zwiększyćSPARK_DRIVER_MEMORY
?Mam kilka sugestii dotyczących wyżej wspomnianego błędu.
● Sprawdź pamięć modułu wykonującego przypisanego jako moduł wykonujący może mieć do czynienia z partycjami wymagającymi więcej pamięci niż przydzielona.
● Spróbuj sprawdzić, czy więcej przetasowań jest na żywo, ponieważ przetasowania są kosztownymi operacjami, ponieważ obejmują one operacje we / wy dysku, serializację danych i sieciowe operacje we / wy
● Użyj połączeń rozgłoszeniowych
● Unikaj używania groupByKey i spróbuj zamienić na ReduceByKey
● Unikaj używania dużych obiektów Java wszędzie tam, gdzie ma miejsce tasowanie
źródło
Z mojego zrozumienia powyższego kodu, ładuje on plik, wykonuje operację mapowania i zapisuje go z powrotem. Nie ma operacji wymagającej odtwarzania losowego. Ponadto, nie ma operacji wymagającej dostarczenia danych do sterownika, dlatego dostrajanie czegokolwiek związanego z tasowaniem lub sterownikiem może nie mieć wpływu. Sterownik ma problemy, gdy jest zbyt wiele zadań, ale było to tylko do wersji Spark 2.0.2. Mogą się zdarzyć dwie rzeczy.
źródło
Ustawienie tych dokładnych konfiguracji pomogło rozwiązać problem.
źródło