Sparkin määrittäminen YARNissa

Habr, hei! Eilen päällä Apache Sparkille omistettu tapaaminen, Rambler&Co:n kavereilta, osallistujilta oli melko paljon kysymyksiä tämän työkalun määrittämisestä. Päätimme seurata hänen jalanjälkiä ja jakaa kokemuksemme. Aihe ei ole helppo - joten kutsumme sinut jakamaan kokemuksesi kommenteissa, ehkä myös ymmärrämme ja käytämme jotain väärin.

Pieni johdatus Sparkin käyttöön. Meillä on kolmen kuukauden ohjelma "Big Data Specialist", ja koko toisen moduulin osallistujamme työskentelevät tällä instrumentilla. Tästä syystä meidän tehtävämme järjestäjinä on valmistella klusteri käytettäväksi tällaisessa tapauksessa.

Käyttömme erikoisuutena on, että Sparkilla samanaikaisesti työskentelevien henkilöiden määrä voi olla yhtä suuri kuin koko ryhmä. Esimerkiksi seminaarissa, kun kaikki yrittävät jotain yhtä aikaa ja toistavat opettajamme perässä. Ja tämä ei ole paljon - joskus jopa 40 henkilöä. Maailmassa ei todennäköisesti ole monia yrityksiä, jotka kohtaavat tällaisen käyttötapauksen.

Seuraavaksi kerron sinulle, kuinka ja miksi valitsimme tietyt konfigurointiparametrit.

Aloitetaan aivan alusta. Sparkilla on kolme vaihtoehtoa toimia klusterissa: itsenäinen, käyttämällä Mesosia ja käyttämällä YARNia. Päätimme valita kolmannen vaihtoehdon, koska se oli meille järkevää. Meillä on jo hadoop-klusteri. Osallistujamme tuntevat jo hyvin sen arkkitehtuurin. Käytetään LANKAA.

spark.master=yarn

Vielä mielenkiintoisempaa. Jokaisella näistä kolmesta käyttöönottovaihtoehdosta on kaksi käyttöönottovaihtoehtoa: asiakas ja klusteri. Perustuu dokumentointi ja Internetin erilaisista linkeistä voimme päätellä, että asiakas soveltuu vuorovaikutteiseen työhön - esimerkiksi jupyter-muistikirjan kautta ja klusteri sopii paremmin tuotantoratkaisuihin. Meidän tapauksessamme olimme kiinnostuneita interaktiivisesta työstä, joten:

spark.deploy-mode=client

Yleensä tästä lähtien Spark toimii jotenkin LANKAlla, mutta tämä ei riittänyt meille. Koska meillä on ohjelma big datasta, välillä osallistujat eivät riittäneet tasaisen resurssien viipaloinnin puitteissa saadulle. Ja sitten löysimme mielenkiintoisen asian - dynaamisen resurssien allokoinnin. Lyhyesti sanottuna pointti on tämä: jos sinulla on vaikea tehtävä ja klusteri on vapaa (esimerkiksi aamulla), tämän vaihtoehdon käyttäminen Spark voi antaa sinulle lisäresursseja. Välttämättömyys lasketaan siellä ovelan kaavan mukaan. Emme mene yksityiskohtiin - se toimii hyvin.

spark.dynamicAllocation.enabled=true

Asetimme tämän parametrin, ja käynnistyksen yhteydessä Spark kaatui eikä käynnistynyt. Juuri niin, koska minun oli pakko lukea se dokumentointi varovaisemmin. Siinä sanotaan, että jotta kaikki olisi kunnossa, sinun on otettava käyttöön myös lisäparametri.

spark.shuffle.service.enabled=true

Miksi sitä tarvitaan? Kun työmme ei enää vaadi niin paljon resursseja, Sparkin pitäisi palauttaa ne yhteiseen pooliin. Melkein minkä tahansa MapReduce-tehtävän aikaa vievin vaihe on Shuffle-vaihe. Tämän parametrin avulla voit tallentaa tässä vaiheessa luodut tiedot ja vapauttaa suorittajat vastaavasti. Ja toimeenpanija on prosessi, joka laskee kaiken työntekijästä. Siinä on tietty määrä prosessoriytimiä ja tietty määrä muistia.

Tämä parametri on lisätty. Kaikki näytti toimivan. Tuli havaittavaksi, että osallistujille annettiin itse asiassa enemmän resursseja, kun he tarvitsivat niitä. Mutta toinen ongelma ilmaantui - jossain vaiheessa muut osallistujat heräsivät ja halusivat myös käyttää Sparkia, mutta siellä kaikki oli kiireistä ja he olivat tyytymättömiä. Niitä voidaan ymmärtää. Aloimme tarkastella asiakirjoja. Kävi ilmi, että on olemassa useita muita parametreja, joilla voidaan vaikuttaa prosessiin. Esimerkiksi jos toimeenpanija on valmiustilassa, minkä ajan kuluttua siitä voidaan ottaa resursseja?

spark.dynamicAllocation.executorIdleTimeout=120s

Meidän tapauksessamme, jos toimeenpanijasi eivät tee mitään kahteen minuuttiin, palauta heidät yhteiseen pooliin. Mutta tämä parametri ei aina riittänyt. Oli selvää, että henkilö ei ollut tehnyt mitään pitkään aikaan, eikä resursseja vapautunut. Kävi ilmi, että on myös erityinen parametri - minkä ajan kuluttua valita välimuistiin tallennettuja tietoja sisältävät suorittajat. Oletuksena tämä parametri oli ääretön! Korjasimme sen.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

Eli jos toimeenpanijasi eivät tee mitään 5 minuuttiin, anna heidät yhteiseen pooliin. Tässä tilassa resurssien vapauttamisen ja myöntämisen nopeus suurelle määrälle käyttäjiä on tullut kunnolliseksi. Tyytymättömyyden määrä on vähentynyt. Mutta päätimme mennä pidemmälle ja rajoittaa suorittajien enimmäismäärää hakemusta kohti - olennaisesti ohjelman osallistujaa kohti.

spark.dynamicAllocation.maxExecutors=19

Nyt tietysti on tyytymättömiä toisella puolella - "klusteri on tyhjäkäynnillä, ja minulla on vain 19 toimeenpanijaa", mutta mitä voit tehdä? Tarvitsemme jonkinlaisen oikean tasapainon. Kaikkia ei voi tehdä onnelliseksi.

Ja vielä yksi pieni tarina, joka liittyy tapauksemme yksityiskohtiin. Jotenkin monet ihmiset olivat myöhässä käytännön tunnilta, eikä Spark jostain syystä lähtenyt heidän puolestaan ​​käyntiin. Tarkastelimme vapaiden resurssien määrää - se näyttää olevan siellä. Kipinän pitäisi käynnistyä. Onneksi siihen mennessä dokumentaatio oli jo lisätty alakuoreen jonnekin ja muistimme, että Spark etsii käynnistyessään porttia, josta aloittaa. Jos alueen ensimmäinen portti on varattu, se siirtyy järjestyksessä seuraavaan. Jos se on ilmainen, se kaappaa. Ja siellä on parametri, joka osoittaa yritysten enimmäismäärän tätä varten. Oletusarvo on 16. Määrä on pienempi kuin ryhmämme henkilömäärä luokassa. Näin ollen 16 yrityksen jälkeen Spark luovutti ja sanoi, että en voinut aloittaa. Olemme korjanneet tämän asetuksen.

spark.port.maxRetries=50

Seuraavaksi kerron joistakin asetuksista, jotka eivät liity kovinkaan tapauksemme erityispiirteisiin.

Sparkin käynnistämiseksi nopeammin on suositeltavaa arkistoida SPARK_HOME-kotihakemistossa oleva jars-kansio ja laittaa se HDFS:ään. Silloin hän ei tuhlaa aikaa näiden jarnikien lataamiseen työntekijöiden toimesta.

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

On myös suositeltavaa käyttää kryoa serialisoijana toiminnan nopeuttamiseksi. Se on optimoitumpi kuin oletus.

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

Ja Sparkissa on myös pitkäaikainen ongelma, että se usein kaatuu muistista. Usein tämä tapahtuu sillä hetkellä, kun työntekijät ovat laskeneet kaiken ja lähettäneet tuloksen kuljettajalle. Teimme tätä parametria suuremmaksi itsellemme. Oletuksena se on 1 Gt, teimme siitä 3.

spark.driver.maxResultSize=3072

Ja lopuksi jälkiruokana. Kuinka päivittää Spark versioon 2.1 HortonWorks-jakelussa - HDP 2.5.3.0. Tämä HDP-versio sisältää esiasennetun version 2.0, mutta päätimme kerran itse, että Spark kehittyy melko aktiivisesti, ja jokainen uusi versio korjaa joitain bugeja sekä tarjoaa lisäominaisuuksia, mukaan lukien python API:lle, joten päätimme, mitä tarvitsee tehty on päivitys.

Ladattu versio Hadoop 2.7:n viralliselta verkkosivustolta. Pura se ja laita se HDP-kansioon. Asensimme symlinkit tarpeen mukaan. Käynnistämme sen - se ei käynnisty. Kirjoittaa erittäin outo virhe.

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

Googlaamisen jälkeen saimme selville, että Spark päätti olla odottamatta Hadoopin syntymää ja päätti käyttää pelipaidan uutta versiota. He itse väittelevät keskenään tästä aiheesta JIRAssa. Ratkaisu oli ladata jersey-versio 1.17.1. Aseta tämä SPARK_HOMEn purkkikansioon, pakkaa se uudelleen ja lataa se HDFS:ään.

Kiertimme tämän virheen, mutta syntyi uusi ja melko virtaviivaistettu virhe.

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

Samaan aikaan yritämme ajaa versiota 2.0 - kaikki on ok. Yritä arvata, mitä tapahtuu. Tutkimme tämän sovelluksen lokeja ja näimme jotain tällaista:

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

Yleensä jostain syystä hdp.versio ei ratkennut. Googlaamisen jälkeen löysimme ratkaisun. Sinun täytyy mennä Ambarin LANKA-asetuksiin ja lisätä sinne parametri mukautettuun lankasivustoon:

hdp.version=2.5.3.0-37

Tämä taika auttoi, ja Spark lähti liikkeelle. Testasimme useita jupyter-kannettaviamme. Kaikki toimii. Olemme valmiita ensimmäiseen Spark-tuntiin lauantaina (huomenna)!

UPD. Oppitunnin aikana paljastui toinen ongelma. YARN lopetti jossain vaiheessa säiliöiden tarjoamisen Sparkille. YARNissa oli tarpeen korjata parametri, joka oletuksena oli 0.2:

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

Eli vain 20 % resursseista osallistui resurssien jakamiseen. Parametrien muuttamisen jälkeen ladattiin LANKA uudelleen. Ongelma ratkesi ja myös muut osallistujat pystyivät ajamaan kipinäkontekstia.

Lähde: will.com

Lisää kommentti