Konfigurácia Spark na YARN

Habr, ahoj! Včera dňa stretnutie venované Apache Spark, od chalanov z Rambler&Co, bolo od účastníkov pomerne veľa otázok týkajúcich sa konfigurácie tohto nástroja. Rozhodli sme sa ísť v jeho stopách a podeliť sa o svoje skúsenosti. Téma nie je jednoduchá - preto vás pozývame, aby ste sa o svoje skúsenosti podelili v komentároch, možno aj my chápeme a používame niečo nesprávne.

Malý úvod do toho, ako používame Spark. Máme trojmesačný program "Špecialista na veľké údaje"a počas druhého modulu naši účastníci pracujú na tomto nástroji. Našou úlohou ako organizátorov je preto pripraviť klaster na použitie v takomto prípade.

Zvláštnosťou nášho použitia je, že počet ľudí súčasne pracujúcich na Sparku sa môže rovnať celej skupine. Napríklad na seminári, keď všetci naraz niečo skúšajú a opakujú po našom učiteľovi. A to nie je veľa - niekedy až 40 ľudí. Na svete asi nie je veľa spoločností, ktoré čelia takémuto prípadu použitia.

Ďalej vám poviem, ako a prečo sme vybrali určité konfiguračné parametre.

Začnime od úplného začiatku. Spark má 3 možnosti na spustenie v klastri: samostatný, pomocou Mesos a pomocou YARN. Rozhodli sme sa pre tretiu možnosť, pretože nám to dávalo zmysel. Hadoop cluster už máme. Naši účastníci už dobre poznajú jeho architektúru. Použime PRIADZU.

spark.master=yarn

Ďalej zaujímavejšie. Každá z týchto 3 možností nasadenia má 2 možnosti nasadenia: klient a klaster. Na základe dokumentáciu a rôznych odkazoch na internete môžeme konštatovať, že klient je vhodný na interaktívnu prácu – napríklad cez jupyter notebook a cluster je vhodnejší na produkčné riešenia. V našom prípade nás zaujala interaktívna práca, preto:

spark.deploy-mode=client

Vo všeobecnosti bude Spark odteraz nejako fungovať na PRIADZE, ale to nám nestačilo. Keďže máme program o veľkých dátach, niekedy účastníkom nestačilo to, čo sa podarilo získať v rámci rovnomerného krájania zdrojov. A potom sme zistili zaujímavú vec – dynamickú alokáciu zdrojov. Stručne povedané, ide o toto: ak máte náročnú úlohu a klaster je voľný (napríklad ráno), pomocou tejto možnosti vám Spark môže poskytnúť ďalšie zdroje. Nevyhnutnosť sa tam vypočítava podľa prefíkaného vzorca. Nebudeme zachádzať do detailov - funguje to dobre.

spark.dynamicAllocation.enabled=true

Nastavili sme tento parameter a po spustení sa Spark zrútil a nespustil sa. Je to tak, pretože som si to musel prečítať dokumentácia opatrnejšie. Uvádza, že na to, aby bolo všetko v poriadku, je potrebné povoliť aj doplnkový parameter.

spark.shuffle.service.enabled=true

Prečo je to potrebné? Keď už naša práca nebude vyžadovať toľko zdrojov, Spark by ich mal vrátiť do spoločného fondu. Časovo najnáročnejšia fáza takmer každej úlohy MapReduce je fáza Shuffle. Tento parameter umožňuje uložiť údaje, ktoré sa v tejto fáze vygenerujú, a podľa toho uvoľniť vykonávateľov. A exekútor je proces, ktorý všetko vypočítava na pracovníka. Má určitý počet procesorových jadier a určité množstvo pamäte.

Tento parameter bol pridaný. Zdalo sa, že všetko funguje. Ukázalo sa, že účastníci v skutočnosti dostali viac zdrojov, keď ich potrebovali. Vyskytol sa však ďalší problém – v istom momente sa zobudili ďalší účastníci a chceli použiť aj Spark, no všetko tam bolo zaneprázdnené a oni boli nešťastní. Dá sa im rozumieť. Začali sme prezerať dokumentáciu. Ukázalo sa, že existuje množstvo ďalších parametrov, ktorými sa dá proces ovplyvniť. Ak je exekútor napríklad v pohotovostnom režime, po akom čase mu môžu byť prostriedky odoberané?

spark.dynamicAllocation.executorIdleTimeout=120s

V našom prípade, ak vaši exekútori dve minúty nič nerobia, tak ich prosím vráťte do spoločného bazéna. Tento parameter však nie vždy stačil. Bolo jasné, že daná osoba už dlho nič nerobí a zdroje sa neuvoľňujú. Ukázalo sa, že existuje aj špeciálny parameter - po akom čase vybrať spúšťače, ktoré obsahujú údaje vo vyrovnávacej pamäti. V predvolenom nastavení bol tento parameter nekonečno! Opravili sme to.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

To znamená, že ak vaši exekútori nerobia 5 minút nič, dajte ich do spoločného bazéna. V tomto režime sa rýchlosť uvoľňovania a vydávania zdrojov pre veľký počet používateľov stala slušnou. Miera nespokojnosti sa znížila. Rozhodli sme sa však ísť ďalej a obmedziť maximálny počet vykonávateľov na jednu žiadosť – v podstate na jedného účastníka programu.

spark.dynamicAllocation.maxExecutors=19

Samozrejme, na druhej strane sú nespokojní ľudia – „klaster je nečinný a ja mám len 19 vykonávateľov,“ ale čo sa dá robiť, potrebujeme nejakú správnu rovnováhu. Nemôžete urobiť všetkých šťastnými.

A ešte jeden malý príbeh súvisiaci so špecifikami nášho prípadu. Viacerí ľudia nejako meškali na praktickú hodinu a z nejakého dôvodu im Spark nezačal. Pozreli sme sa na množstvo voľných zdrojov – zdá sa, že tam sú. Spark by mal začať. Našťastie v tom čase už bola dokumentácia niekde pridaná do subkortexu a spomenuli sme si, že po spustení Spark hľadá port, na ktorom by mal začať. Ak je prvý port v rozsahu obsadený, presunie sa na ďalší v poradí. Ak je zadarmo, zachytáva. A existuje parameter, ktorý označuje maximálny počet pokusov. Predvolená hodnota je 16. Počet je menší ako počet ľudí v našej skupine v triede. Preto sa Spark po 16 pokusoch vzdal a povedal, že nemôžem začať. Tento parameter sme opravili.

spark.port.maxRetries=50

Ďalej vám poviem o niektorých nastaveniach, ktoré veľmi nesúvisia so špecifikami nášho prípadu.

Pre rýchlejšie spustenie Sparku sa odporúča archivovať priečinok jars umiestnený v domovskom adresári SPARK_HOME a umiestniť ho na HDFS. Potom nebude strácať čas nakladaním týchto jarnikov pracovníkmi.

spark.yarn.archive=hdfs:///tmp/spark-archive.zip

Odporúča sa tiež použiť kryo ako serializátor pre rýchlejšiu prevádzku. Je optimalizovanejší ako predvolený.

spark.serializer=org.apache.spark.serializer.KryoSerializer

A so Sparkom je tiež dlhoročný problém, že často padá po pamäti. Často sa to stane v momente, keď pracovníci všetko spočítali a výsledok pošlú vodičovi. Tento parameter sme pre seba zväčšili. Štandardne je to 1 GB, my sme to urobili 3.

spark.driver.maxResultSize=3072

A nakoniec ako dezert. Ako aktualizovať Spark na verziu 2.1 v distribúcii HortonWorks - HDP 2.5.3.0. Táto verzia HDP obsahuje predinštalovanú verziu 2.0, ale raz sme sa sami rozhodli, že Spark sa vyvíja pomerne aktívne a každá nová verzia opravuje niektoré chyby a poskytuje ďalšie funkcie, vrátane python API, takže sme sa rozhodli, čo je potrebné be done je aktualizácia.

Stiahnite si verziu z oficiálnej stránky pre Hadoop 2.7. Rozbaľte ho a vložte do priečinka HDP. Symbolické odkazy sme nainštalovali podľa potreby. Spustíme to - nespustí sa. Píše veľmi nejasnú chybu.

java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig

Po googli sme zistili, že Spark sa rozhodol nečakať, kým sa nenarodí Hadoop, a rozhodol sa použiť novú verziu dresu. Sami sa na túto tému v JIRA dohadujú. Riešením bolo stiahnuť verzia dresu 1.17.1. Umiestnite ho do priečinka pohárov v SPARK_HOME, znova ho zazipsujte a nahrajte do HDFS.

Túto chybu sme obišli, no vznikla nová a pomerne zjednodušená.

org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master

Zároveň sa snažíme spustiť verziu 2.0 - všetko je ok. Skúste uhádnuť, čo sa deje. Pozreli sme sa do denníkov tejto aplikácie a videli sme niečo takéto:

/usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jar

Vo všeobecnosti sa z nejakého dôvodu hdp.version nevyriešil. Po googli sme našli riešenie. Musíte prejsť do nastavení PRIADZE v Ambari a pridať tam parameter na vlastnú stránku priadze:

hdp.version=2.5.3.0-37

Táto mágia pomohla a Spark vzlietol. Testovali sme niekoľko našich notebookov Jupyter. Všetko funguje. V sobotu (zajtra) sme pripravení na prvú lekciu Spark!

DUP. Počas hodiny vyšiel najavo ďalší problém. V určitom okamihu spoločnosť YARN prestala poskytovať kontajnery pre Spark. V YARN bolo potrebné opraviť parameter, ktorý bol štandardne 0.2:

yarn.scheduler.capacity.maximum-am-resource-percent=0.8

To znamená, že len 20 % zdrojov sa podieľalo na rozdeľovaní zdrojov. Po zmene parametrov sme znovu nabili PRIADZU. Problém bol vyriešený a zvyšok účastníkov bol tiež schopný spustiť kontext.

Zdroj: hab.com

Pridať komentár