Ahoj Habr! Včera na , 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 , 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 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=clientOd 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=trueTento parameter sme nastavili, a pri spustení Sparku sa objavila chyba a nespustil sa. Je to správne, lebo bolo treba čítať pozornejšie. Je tam uvedené, že na to, aby všetko fungovalo, je potrebné ešte zapnúť ďalší parameter.
spark.shuffle.service.enabled=trueNač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=120sV 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=600sTeda, 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=19Teraz 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.zipPre 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.KryoSerializerExistuje 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=3072A 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/ClientConfigPo 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ť . 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 masterSnaží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}.jarV 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-37Tá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
