2015-11-30 58 views
8

Używam klastra EMR (wersja emr-4.2.0) dla Sparka przy użyciu flagi Amazon specyficznej maximizeResourceAllocation, zgodnie z dokumentacją here. Zgodnie z tymi dokumentami "ta opcja oblicza maksymalne zasoby obliczeniowe i pamięci dostępne dla executora w węźle w grupie węzłów rdzenia i ustawia odpowiednie ustawienia wartości iskrzenia z tymi informacjami".Spark + EMR z ustawieniem "maximResourceAllocation" w Amazon nie używa wszystkich rdzeni/voidów

Używam klastra za pomocą instancji m3.2xlarge dla węzłów roboczych. Używam pojedynczego m3.xlarge dla mastera YARN - najmniejszej instancji m3, na którą mogę ją uruchomić, ponieważ nie robi zbyt wiele.

Sytuacja jest następująca: Kiedy uruchamiam zadanie Spark, liczba żądanych rdzeni dla każdego executora wynosi 8. (Mam to tylko po skonfigurowaniu "yarn.scheduler.capacity.resource-calculator": "org.apache.hadoop.yarn.util.resource.DominantResourceCalculator", którego nie ma w dokumentacji, ale dygresja). Wydaje się to mieć sens, ponieważ zgodnie z these docs m3.2xlarge ma 8 "vCPUs". Jednak w samych rzeczywistych instancjach, w węźle /etc/hadoop/conf/yarn-site.xml, każdy węzeł jest skonfigurowany jako yarn.nodemanager.resource.cpu-vcores ustawiony na 16. Chciałbym (jak sądzę) sądzić, że musi to być spowodowane hiperwentylacją lub być może jakąś inną fancyzmem sprzętowym.

Problem polega na tym, że gdy używam maximizeResourceAllocation, otrzymuję liczbę "vCPU", które ma typ Amazon Instance, który wydaje się być tylko połową liczby skonfigurowanych "VCores", które YARN działa na węzeł; w rezultacie executor używa tylko połowy rzeczywistych zasobów obliczeniowych instancji.

Czy to błąd w Amazon EMR? Czy inne osoby doświadczają tego samego problemu? Czy jest jeszcze jakaś magiczna nieudokumentowana konfiguracja, której mi brakuje?

Odpowiedz

2

Przy tym ustawieniu powinieneś otrzymać 1 executor na każde wystąpienie (oprócz mastera), każde z 8 rdzeniami i około 30 GB pamięci RAM.

Czy interfejs użytkownika Spark na stronie http: //: 8088/nie pokazuje tej alokacji?

Nie jestem pewien, czy ustawienie ma naprawdę dużą wartość w porównaniu z inną wspomnianą na tej stronie, "Włączanie dynamicznego przydzielania executorów". To pozwoli Sparkowi zarządzać własną liczbą instancji dla zadania, a jeśli uruchomisz zadanie z 2 rdzeniami procesora i 3G pamięci RAM na executor, uzyskasz całkiem dobry stosunek CPU do pamięci dla rozmiarów instancji EMR.

+0

Pokazuje to; ale problem polega na tym, że rdzenie "8" są w rzeczywistości tylko 8 z 16 "VCores" przydzielonych przez YARN; połowa rzeczywistych zasobów procesora w komputerze pozostaje bezczynna. Ponieważ próbuję uruchomić intensywne zadania CPU, jest to strata CPU (i oczywiście pieniędzy!) – retnuH

+2

Rdzenie są po prostu abstrakcją samego typu instancji. Nie ma faktycznego powiązania z rdzeniami, więc executorzy wykorzystają jak najwięcej CPU żądań aplikacji. Jedyne wiązanie przychodzi podczas używania DominantResourceCalculator dla harmonogramu. Jedną z rzeczy do zapamiętania jest dla tej instancji domyślna konfiguracja EMR podwójna wartość vcore opowiedziana przędzy, aby poprawić wykorzystanie procesora za pomocą MapReduce. Właściwość MaximumResourceAllocation analizowała definicję rdzenia typu instancji. – ChristopherB

22

OK, po wielu eksperymentach udało mi się wyśledzić problem. Zamierzam zgłosić tu swoje ustalenia, aby pomóc ludziom uniknąć frustracji w przyszłości.

  • Chociaż istnieje rozbieżność między pytaniami 8 rdzeni a 16 VCorami, o których WIELE wie, nie wydaje się to mieć znaczenia. YARN nie używa cgroups ani niczego szczególnego do faktycznego ograniczenia liczby procesorów, z których może korzystać executor.
  • "Rdzenie" na executorze są w rzeczywistości nieco mylące. W rzeczywistości jest to liczba równoczesnych zadań wykonywanych przez executora w dowolnym momencie; zasadniczo sprowadza się do tego, ile wątków wykonuje "praca" na każdym executorze.
  • Kiedy maximizeResourceAllocation jest ustawione, po uruchomieniu programu Spark, ustawia właściwość spark.default.parallelism być liczba instancji rdzeni (lub „vCPUs”) dla wszystkich przypadkach non-master, które były w zestawie w czasie kreacja. Jest to prawdopodobnie za mały nawet w normalnych przypadkach; Słyszałem, że zalecane jest ustawienie 4x liczby rdzeni potrzebnych do uruchomienia twoich zadań. Pomoże to upewnić się, że jest wystarczająco dużo zadań dostępnych na danym etapie, aby utrzymać procesory zajęte na wszystkich executorach.
  • Gdy masz dane pochodzące z różnych serii różnych programów iskrzenia, twoje dane (w RDD lub formacie Parkiet lub czymkolwiek) są prawdopodobnie zapisywane z różną liczbą partycji. Podczas uruchamiania programu Spark, upewnij się, że dane dotyczące ponownego dzielenia danych są albo w czasie ładowania, albo przed zadaniem szczególnie obciążającym procesor. Ponieważ masz dostęp do ustawienia spark.default.parallelism w czasie wykonywania, może to być wygodna liczba do ponownego dzielenia na.

TL; DR

  1. maximizeResourceAllocation zrobi prawie wszystko dla ciebie poprawnie z wyjątkiem ...
  2. Prawdopodobnie chcesz jawnie ustawić spark.default.parallelism 4x liczbę instancji rdzeni chcesz zadanie do uruchom na "kroku" (w EMR)/"aplikacji" (w języku YARN), tzn. ustaw go za każdym razem, gdy i ...
  3. Upewnij się, że w ramach twojego programu, że twoje dane są odpowiednio podzielone na partycje (tj. chcą wiele partycji), aby umożliwić Spark parallelize go prawidłowo
+0

Dodałbym, że użycie dynamicznego obliczania zasobów Sparka może być tutaj również użyteczne (http://docs.aws.amazon.com/ElasticMapReduce/latest/ReleaseGuide/emr-spark-configure.html#spark-dynamic-allocation) . Dodatkowo, użytkownik może nadmuchać vcores dla typu instancji, aby osiągnąć dobre na zadanie na każde saldo executora z rzeczywistym wykorzystaniem procesora. – ChristopherB

0

w wersji 3.x EMR, to maximizeResourceAllocation został zrealizowany przy stole odniesienia: https://github.com/awslabs/emr-bootstrap-actions/blob/master/spark/vcorereference.tsv

on używany przez skrypt powłoki: maximize-spark-default-config, w tego samego repozytu, możesz rzucić okiem, jak to zaimplementowali.

Może w nowej wersji EMR 4, ta tabela referencyjna była w jakiś sposób błędna ... Wierzę, że możesz znaleźć cały ten skrypt AWS w swoim EC2 instancji EMR, powinien być zlokalizowany w /usr/lib/spark lub /opt/aws lub coś w tym stylu.

tak, przynajmniej można pisać własne skrypty dla tego bootstrap action w EMR 4, z prawidłowym tabeli odniesienia, podobny do realizacji w EMR 3.x

Ponadto, ponieważ mamy zamiar użyć STUPS infrastruktura, warto wziąć wygląd urządzenia STUPS iskry: https://github.com/zalando/spark-appliance

można jednoznacznie określić liczbę rdzeni poprzez ustawienie parametru senza DefaultCores podczas wdrażania klastra zapłonową

niektóre z podświetleniem tego urządzenia w porównaniu do EMR to:

stanie wykorzystać go nawet t2 typu instancji, auto-skalowalne oparte na rolach jak inne STUPS urządzenia itp

i można łatwo wdrożyć klaster w trybie HA z zookeeperem, więc brak SPOF na węźle nadrzędnym, tryb HA w EMR jest obecnie nadal niemożliwy i wierzę, że EMR jest głównie przeznaczony dla "dużych klastrów tymczasowo do zadań analizy ad-hoc", a nie do "dedykowanych klaster, który jest stale włączony ", więc tryb HA nie będzie możliwy w pobliżu z EMR.