Konfigurácia Spark na YARN

Ahoj Habr! Včera na meet-u venovanom Apache Spark, od chalanov z Rambler&Co, bolo skutočne veľa otázok od účastníkov týkajúcich sa konfigurácie tohto nástroja. Rozhodli sme sa podeliť o naše skúsenosti. Téma nie je jednoduchá — preto navrhujeme zdieľať vaše skúsenosti aj v komentároch, možno aj my niečo nepochopíme alebo nesprávne používame.

Krátke úvodné slovo — ako používame Spark. Máme trojmesačný program „Špecialista na veľké dáta“, a v celom druhom module naši účastníci pracujú s týmto nástrojom. Našou úlohou ako organizátorov je pripraviť klastra na použitie v rámci tohto prípadu.

Špecifickosť nášho použitia spočíva v tom, že počet ľudí, ktorí pracujú na Sparku súčasne, môže byť rovný celému tímu. Napríklad na seminári, kedy všetci skúšajú a opakujú po našom lektorovi. A to je dosť — občas až 40 ľudí. Pravdepodobne nie je veľa firiem na svete, ktoré sa stretávajú s takýmto spôsobom použitia.

Ďalej vám poviem, ako a prečo sme vyberali tie alebo iné parametre konfigurácie.

Začneme od začiatku. Spark má 3 možnosti, ako pracovať na klastri: standalone, s použitím Mesos a s použitím YARN. Rozhodli sme sa zvoliť tretiu možnosť, pretože pre nás dávala zmysel. Už máme hadoop-klaster. Naši účastníci sú už dobre oboznámení s jeho architektúrou. Použime YARN.

spark.master=yarn

Ďalej je to zaujímavejšie. Každá z týchto 3 možností nasadenia má 2 možnosti deploy: client a cluster. Na základe dokumenácie a rôznych odkazov na internete možno usúdiť, že client je vhodný pre interaktívnu prácu — napríklad cez jupyter notebook, zatiaľ čo cluster je viac vhodný pre produkčné riešenia. V našom prípade nás zaujímala interaktívna práca, preto:

spark.deploy-mode=client

Od tohto momentu začne Spark nejakým spôsobom fungovať na YARN, ale to nám nestačilo. Keďže máme program o veľkých dátach, niekedy účastníkom chýbalo to, čo sa dosahovalo v rámci rovnomerného rozdelenia zdrojov. A tu sme objavili zaujímavú vec — dynamickú alokáciu zdrojov. V skratke, podstata je nasledujúca: ak máte náročnú úlohu a klaster je voľný (napríklad ráno), tak pomocou tejto možnosti vám Spark môže poskytnúť ďalšie zdroje. Potreba sa počíta pomocou komplikovanej formule. Nechceme sa zaoberať podrobnosťami — funguje to celkom dobre.

spark.dynamicAllocation.enabled=true

Tento parameter sme nastavili, a pri spustení Sparku sa objavila chyba a nespustil sa. Je to správne, lebo bolo treba čítať dokumentácii pozornejšie. Je tam uvedené, že na to, aby všetko fungovalo, je potrebné ešte zapnúť ďalší parameter.

spark.shuffle.service.enabled=true

Načo je potrebný? Keď už náš job viac nevyžaduje toľko zdrojov, Spark by mal vrátiť zdroje do spoločného poolu. Najnáročnejšia fáza skoro v každej úlohe MapReduce je fáza Shuffle. Tento parameter umožňuje uchovávať dáta, ktoré vznikajú v tejto fáze, a tým uvoľňovať executors. A executor je proces, ktorý na workeri všetko vypočítava. Má určitý počet procesorových jadier a určitú kapacitu pamäte.

Tento parameter sme pridali. Všetko sa zdalo fungovať. Bolo zjavné, že účastníkom sa začali skutočne poskytovať viac zdrojov, keď ich potrebovali. Ale objavil sa iný problém — v určitom momente sa prebudili aj ďalší účastníci a chceli tiež používať Spark, ale všetko bolo obsadené a boli nespokojní. Môžeme ich pochopiť. Začali sme sa pozerať do dokumentácie. Zistilo sa, že existuje ešte niekoľko parametrov, pomocou ktorých je možné ovplyvniť tento proces. Napríklad, ak je executor v režime čakania — za aký čas je možné vziať mu zdroje?

spark.dynamicAllocation.executorIdleTimeout=120s

V našom prípade, ak vaše executors nič nerobia počas dvoch minút, prosím, vráťte ich do spoločného poolu. Ale ani tento parameter nie vždy stačil. Bolo vidno, že človek už dlho nič nerobí, a zdroje sa neuvoľňovali. Ukázalo sa, že existuje ešte špeciálny parameter — po uplynutí určitého času vyberať executors, ktoré obsahujú cachované dáta. Podľa predvoleného nastavenia bol tento parameter — nekonečno! Opravené.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

Teda, ak vaše executors nič nerobia počas 5 minút, vráťte ich do spoločného poolu. V takomto režime sa rýchlosť uvoľňovania a poskytovania zdrojov pre veľké množstvo používateľov stala akceptovateľnou. Počet nespokojných zákazníkov sa znížil. Ale rozhodli sme sa ísť ďalej a obmedziť maximálny počet executors pre jednu aplikáciu — vlastne pre jedného účastníka programu.

spark.dynamicAllocation.maxExecutors=19

Teraz sa samozrejme objavili nespokojní z druhej strany — "klaster nevyužíva zdroje, a ja mám iba 19 executors", ale čo sa dá robiť — potrebujeme nejakú správnu rovnováhu. Nie všetkých sa podarí urobiť šťastnými.

A ešte jedna malá príhoda, spojená so špecifikou našej situácie. Na jedno praktické cvičenie prišlo niekoľko ľudí neskoro, a ich Spark, prečo nie, neštartoval. Pozreli sme sa na počet voľných zdrojov — zdalo sa, že sú. Spark by mal štartovať. Našťastie, dokumentácia sa už k tomu okamihu zapísala do pamäti, a spomenuli sme si, že pri spustení Spark hľadá port, na ktorom sa spustiť. Ak je prvý port z rozsahu obsadený, prechádza na ďalší v poradí. Ak je voľný, zaberá ho. A existuje parameter, ktorý určuje maximálny počet pokusov pre toto. Podľa predvoleného nastavenia — to je 16. Počet je menší než počet ľudí v našej skupine na cvičení. Zodpovedne, po 16 pokusoch Spark zanechal to a povedal, že nemôžem štartovať. Tento parameter sme opravili.

spark.port.maxRetries=50

Ďalej vám poviem o niektorých nastaveniach, ktoré už nie sú veľmi spojené so špecifikou našej situácie.

Pre rýchlejšie spustenie Sparku sa odporúča zarchivovať priečinok jars, ktorý sa nachádza v domovskom adresári SPARK_HOME, a umiestniť ho na HDFS. Takto sa nebude strácať čas s načítaním týchto jarov po workeroch.

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

Pre rýchlejšie fungovanie sa odporúča použiť ako serializátor kryo. Je optimalizovanejší než ten, ktorý je predvolene nastavený.

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

Existuje aj dlhodobý problém Spark, že často spadne kvôli pamäti. Často sa to deje vtedy, keď pracovníci všetko spočítali a posielajú výsledok na ovládač. Tento parameter sme nastavili väčší. Predvolene je 1GB, my sme ho nastavili na 3.

spark.driver.maxResultSize=3072

A posledná vec, ako dezert. Ako aktualizovať Spark na verziu 2.1 na distribúcii HortonWorks — HDP 2.5.3.0. Táto verzia HDP obsahuje predinštalovanú verziu 2.0, ale raz sme sa rozhodli, že Spark sa vyvíja dosť aktívne a každá nová verzia opravuje nejaké chyby a poskytuje nové možnosti, vrátane python API, preto sme sa rozhodli, že je potrebné vykonať aktualizáciu.

Stiahli sme verziu z oficiálnej stránky pre Hadoop 2.7. Rozbalili sme ju a preniesli do priečinka s HDP. Nastavili sme symbolické odkazy tak, ako treba. Spúšťame — nechce sa spustiť. Zobrazuje veľmi nezrozumiteľnú chybu.

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

Po googlení sme zistili, že Spark sa rozhodol nečakať, kým Hadoop vyjde, a rozhodol sa použiť novú verziu jersey. Sami sa s tým hádajú na JIRA. Riešením bolo — stiahnuť jersey verziu 1.17.1. Preniesť to do priečinka jars v SPARK_HOME, znova vytvoriť zip a preniesť na HDFS.

Túto chybu sme obchádzali, ale objavila sa nová a dosť nejasná.

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

Snažíme sa spustiť verziu 2.0 — všetko je v poriadku. Skús uhádnuť, v čom je problém. Pozreli sme sa do logov tejto aplikácie a videli sme niečo takéto:

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

V skratke, z nejakých dôvodov hdp.version nebola rozlíšená. Po googlení sme našli riešenie. Musíte v Ambari ísť do nastavení YARN a pridať tam parameter do vlastného yarn-site:

hdp.version=2.5.3.0-37

Táto mágia pomohla a Spark sa rozbehol. Otestovali sme niekoľko našich jupyter notebookov. Všetko funguje. Na prvú hodinu o Sparku v sobotu (už zajtra) sme pripravení!

UPD. Na hodine sa objavil ďalší problém. V určitom momente YARN prestal poskytovať kontajnery pre Spark. V YARN bolo treba upraviť parameter, ktorý bol predvolene nastavený na 0.2:

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

Teda len 20% zdrojov sa zúčastnilo na pridelení zdrojov. Zmenili sme parametre a reštartovali YARN. Problém bol vyriešený a ostatní účastníci tiež mohli spustiť spark context.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster