Spark konfigūravimas YARN

Habr, labas! Vakar susitikimas, skirtas „Apache Spark“., iš Rambler&Co vaikinų, dalyvių sulaukė nemažai klausimų, susijusių su šio įrankio konfigūravimu. Nusprendėme sekti jo pėdomis ir pasidalinti savo patirtimi. Tema nelengva – tad kviečiame pasidalinti patirtimi komentaruose, gal ir mes ką nors suprantame ir panaudojame.

Šiek tiek įvadas, kaip naudojame Spark. Turime trijų mėnesių programą „Didžiųjų duomenų specialistas“, o viso antrojo modulio metu mūsų dalyviai dirba su šiuo instrumentu. Atitinkamai, mūsų, kaip organizatorių, užduotis yra paruošti klasterį naudoti tokiu atveju.

Mūsų naudojimo ypatumas yra tas, kad žmonių, vienu metu dirbančių „Spark“, skaičius gali būti lygus visai grupei. Pavyzdžiui, seminare, kai visi kažką bando vienu metu ir kartoja paskui mūsų mokytoją. Ir tai nėra daug – kartais iki 40 žmonių. Tikriausiai pasaulyje nėra daug įmonių, kurios susiduria su tokiu naudojimo atveju.

Toliau papasakosiu, kaip ir kodėl pasirinkome tam tikrus konfigūracijos parametrus.

Pradėkime nuo pat pradžių. „Spark“ turi 3 parinktis paleisti klasteryje: atskirą, naudojant „Mesos“ ir „YARN“. Nusprendėme rinktis trečią variantą, nes mums tai buvo prasminga. Jau turime „hadoop“ grupę. Mūsų dalyviai jau gerai susipažinę su jo architektūra. Naudokime VERPALUS.

spark.master=yarn

Toliau įdomiau. Kiekviena iš šių 3 diegimo parinkčių turi 2 diegimo parinktis: klientą ir grupę. Pagrįstas dokumentacija ir įvairių nuorodų internete, galime daryti išvadą, kad klientas tinka interaktyviam darbui – pavyzdžiui, per jupyter užrašų knygelę, o klasteris labiau tinka gamybiniams sprendimams. Mūsų atveju mus domino interaktyvus darbas, todėl:

spark.deploy-mode=client

Apskritai, nuo šiol „Spark“ kažkaip dirbs su YARN, bet mums to nepakako. Kadangi turime programą apie didžiuosius duomenis, kartais dalyviams neužteko to, kas buvo gauta tolygiai suskirstant išteklius. Ir tada radome įdomų dalyką – dinamišką išteklių paskirstymą. Trumpai tariant, esmė tokia: jei turite sudėtingą užduotį ir klasteris yra laisvas (pavyzdžiui, ryte), tada naudodami šią parinktį „Spark“ galite suteikti jums papildomų išteklių. Ten būtinybė apskaičiuojama pagal gudrią formulę. Mes nesigilinsime į detales – tai veikia gerai.

spark.dynamicAllocation.enabled=true

Nustatėme šį parametrą, o paleidus „Spark“ sudužo ir neįsijungė. Teisingai, nes turėjau ją perskaityti dokumentacija atsargiau. Jame teigiama, kad norint, kad viskas būtų gerai, reikia įjungti ir papildomą parametrą.

spark.shuffle.service.enabled=true

Kodėl to reikia? Kai mūsų darbui nebereikia tiek daug išteklių, „Spark“ turėtų grąžinti juos į bendrą baseiną. Daugiausiai laiko atimantis beveik bet kurios MapReduce užduoties etapas yra maišymo etapas. Šis parametras leidžia išsaugoti šiame etape sugeneruotus duomenis ir atitinkamai išleisti vykdytojus. O vykdytojas yra procesas, kuris viską apskaičiuoja ant darbuotojo. Jis turi tam tikrą skaičių procesoriaus branduolių ir tam tikrą atminties kiekį.

Šis parametras buvo pridėtas. Atrodė, kad viskas pavyko. Tapo pastebima, kad dalyviams iš tikrųjų buvo suteikta daugiau išteklių, kai jiems jų reikėjo. Tačiau iškilo kita problema – kažkada pabudo kiti dalyviai ir taip pat norėjo pasinaudoti Spark, bet ten viskas buvo užimta, ir jie buvo nepatenkinti. Juos galima suprasti. Pradėjome žiūrėti dokumentus. Paaiškėjo, kad yra nemažai kitų parametrų, kuriais galima daryti įtaką procesui. Pavyzdžiui, jei vykdytojas yra budėjimo režime, po kurio laiko iš jo galima paimti resursus?

spark.dynamicAllocation.executorIdleTimeout=120s

Mūsų atveju, jei jūsų vykdytojai nieko nedaro dvi minutes, prašome grąžinti juos į bendrą baseiną. Tačiau šio parametro ne visada pakako. Buvo aišku, kad žmogus jau seniai nieko neveikė, resursai neatsilaisvino. Paaiškėjo, kad yra ir specialus parametras – po kurio laiko pasirinkti vykdytojus, kuriuose yra talpykloje saugomi duomenys. Pagal numatytuosius nustatymus šis parametras buvo begalybė! Mes tai pataisėme.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

Tai yra, jei jūsų vykdytojai nieko nedaro 5 minutes, atiduokite juos į bendrą baseiną. Šiuo režimu išteklių išleidimo ir išdavimo greitis daugeliui vartotojų tapo tinkamas. Sumažėjo nepasitenkinimo lygis. Tačiau nusprendėme eiti toliau ir apriboti maksimalų vykdytojų skaičių vienai programai – iš esmės vienam programos dalyviui.

spark.dynamicAllocation.maxExecutors=19

Dabar, žinoma, yra nepatenkintų žmonių kitoje pusėje - "klasteris neveikia, o aš turiu tik 19 vykdytojų", bet ką daryti? Reikia kažkokio teisingo balanso. Jūs negalite padaryti visų laimingų.

Ir dar viena nedidelė istorija, susijusi su mūsų bylos specifika. Kažkaip keli žmonės pavėlavo į praktinę pamoką, o kibirkštis jiems kažkodėl neprasidėjo. Pasižiūrėjome, kiek laisvų resursų – atrodo, kad yra. Spark turėtų prasidėti. Laimei, iki to laiko dokumentacija jau buvo kažkur pridėta prie subkortekso ir prisiminėme, kad paleidus Spark ieško prievado, nuo kurio pradėti. Jei pirmasis diapazono prievadas yra užimtas, jis eilės tvarka pereina prie kito. Jei jis nemokamas, jis fiksuoja. Ir yra parametras, nurodantis maksimalų bandymų skaičių. Numatytasis yra 16. Skaičius yra mažesnis nei mūsų grupės žmonių klasėje. Atitinkamai, po 16 bandymų „Spark“ pasidavė ir pasakė, kad negaliu pradėti. Mes pataisėme šį parametrą.

spark.port.maxRetries=50

Toliau papasakosiu apie kai kuriuos nustatymus, kurie nėra labai susiję su mūsų atvejo specifika.

Norint greičiau paleisti Spark, rekomenduojama archyvuoti SPARK_HOME namų kataloge esantį aplanką jars ir įdėti jį į HDFS. Tada jis negaiš laiko krauti šių jarnikus darbininkams.

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

Taip pat rekomenduojama naudoti kryo kaip serializatorių, kad veiktų greičiau. Jis yra labiau optimizuotas nei numatytasis.

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

Taip pat yra ilgalaikė „Spark“ problema, kad ji dažnai užstringa iš atminties. Dažnai tai nutinka tuo metu, kai darbuotojai viską apskaičiavo ir rezultatą išsiunčia vairuotojui. Šį parametrą padidinome patys. Pagal numatytuosius nustatymus tai yra 1 GB, mes padarėme 3.

spark.driver.maxResultSize=3072

Ir galiausiai kaip desertas. Kaip atnaujinti „Spark“ į 2.1 versiją „HortonWorks“ paskirstyme – HDP 2.5.3.0. Šioje HDP versijoje yra iš anksto įdiegta 2.0 versija, tačiau kažkada patys nusprendėme, kad „Spark“ vystosi gana aktyviai, o kiekviena nauja versija ištaiso tam tikras klaidas ir suteikia papildomų funkcijų, įskaitant python API, todėl nusprendėme, ko reikia turi būti atliktas atnaujinimas.

Atsisiųsta versija iš oficialios „Hadoop 2.7“ svetainės. Išpakuokite jį ir įdėkite į HDP aplanką. Mes įdiegėme simbolius pagal poreikį. Mes jį paleidžiame - jis neprasideda. Rašo labai neaiškią klaidą.

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

Paieškoję „Google“ sužinojome, kad „Spark“ nusprendė nelaukti, kol gims „Hadoop“, ir nusprendė naudoti naują marškinėlių versiją. Jie patys ginčijasi tarpusavyje šia tema JIRA. Sprendimas buvo atsisiųsti marškinėlių versija 1.17.1. Įdėkite jį į SPARK_HOME aplanką jars, dar kartą supakuokite ir įkelkite į HDFS.

Mes apėjome šią klaidą, tačiau atsirado nauja ir gana supaprastinta.

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

Tuo pačiu metu bandome paleisti 2.0 versiją – viskas gerai. Pabandykite atspėti, kas vyksta. Peržiūrėjome šios programos žurnalus ir pamatėme kažką panašaus:

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

Apskritai dėl kažkokių priežasčių hdp.version nepavyko išspręsti. Paieškoję „Google“ radome sprendimą. Turite eiti į „YARN“ nustatymus „Ambari“ ir pridėti ten parametrą tinkintoje verpalų svetainėje:

hdp.version=2.5.3.0-37

Ši magija padėjo, ir Spark pakilo. Išbandėme kelis savo „jupyter“ nešiojamuosius kompiuterius. Viskas veikia. Jau šeštadienį (rytoj) ruošiamės pirmajai Spark pamokai!

DUP. Pamokos metu išryškėjo dar viena problema. Tam tikru momentu YARN nustojo tiekti konteinerius Spark. YARN reikėjo ištaisyti parametrą, kuris pagal numatytuosius nustatymus buvo 0.2:

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

Tai yra, tik 20% išteklių dalyvavo skirstant išteklius. Pakeitę parametrus, perkrovėme VERALUS. Problema buvo išspręsta, o kiti dalyviai taip pat galėjo paleisti kontekstą.

Šaltinis: www.habr.com

Добавить комментарий