Konfiguriranje Spark na YARN

Habr, pozdravljeni! Včeraj na srečanje posvečeno Apache Spark, od fantov iz Rambler&Co, je bilo kar nekaj vprašanj udeležencev v zvezi s konfiguracijo tega orodja. Odločili smo se, da gremo po njegovih stopinjah in delimo svoje izkušnje. Tema ni lahka - zato vas vabimo, da svoje izkušnje delite v komentarjih, morda tudi mi razumemo in uporabljamo kaj narobe.

Kratek uvod v to, kako uporabljamo Spark. Imamo trimesečni program "Specialist za velike podatke", skozi drugi modul pa naši udeleženci delajo na tem instrumentu. Zato je naša naloga kot organizatorja, da pripravimo grozd za uporabo v okviru takega primera.

Posebnost naše uporabe je, da je lahko število ljudi, ki hkrati delajo na Sparku, enako celotni skupini. Na primer na seminarju, ko vsi nekaj poskušamo hkrati in ponavljamo za našim učiteljem. In to ni veliko - včasih do 40 ljudi. Verjetno ni veliko podjetij na svetu, ki se soočajo s takim primerom uporabe.

Nato vam bom povedal, kako in zakaj smo izbrali določene konfiguracijske parametre.

Začnimo od samega začetka. Spark ima 3 možnosti za izvajanje v gruči: samostojno, z uporabo Mesosa in z uporabo YARN. Odločili smo se za tretjo možnost, ker se nam je zdela smiselna. Že imamo gručo hadoop. Naši udeleženci že dobro poznajo njegovo arhitekturo. Uporabimo PREJO.

spark.master=yarn

Nadalje bolj zanimivo. Vsaka od teh 3 možnosti uvajanja ima 2 možnosti uvajanja: odjemalec in gruča. Temelji dokumentacijo in raznih povezav na spletu lahko sklepamo, da je klient primeren za interaktivno delo – na primer preko jupyter notebooka, grozd pa je primernejši za produkcijske rešitve. V našem primeru nas je zanimalo interaktivno delo, zato:

spark.deploy-mode=client

Na splošno bo Spark od zdaj naprej nekako delal na YARN, vendar nam to ni bilo dovolj. Ker imamo program o velikih podatkih, udeležencem včasih ni bilo dovolj pridobljenega v okviru enakomernega razrezovanja virov. In potem smo ugotovili zanimivo stvar - dinamično dodeljevanje virov. Skratka, bistvo je naslednje: če imate težko nalogo in je gruča prosta (na primer zjutraj), vam lahko s to možnostjo Spark zagotovi dodatne vire. Nujnost se tam izračuna po premeteni formuli. Ne bomo šli v podrobnosti - deluje dobro.

spark.dynamicAllocation.enabled=true

Nastavili smo ta parameter in ob zagonu se je Spark zrušil in se ni zagnal. Tako je, saj sem moral prebrati dokumentacijo bolj previdno. Navaja, da moraš omogočiti še dodaten parameter, da bo vse v redu.

spark.shuffle.service.enabled=true

Zakaj je to potrebno? Ko naše delo ne bo več zahtevalo toliko virov, bi jih moral Spark vrniti v skupni bazen. Najbolj zamudna stopnja v skoraj vseh opravilih MapReduce je faza Shuffle. Ta parameter vam omogoča, da shranite podatke, ki so ustvarjeni na tej stopnji, in ustrezno sprostite izvajalce. In izvršitelj je proces, ki delavcu vse poračuna. Ima določeno število procesorskih jeder in določeno količino pomnilnika.

Ta parameter je bil dodan. Zdelo se je, da vse deluje. Postalo je opazno, da so udeleženci dejansko dobili več sredstev, ko so jih potrebovali. Toda pojavila se je druga težava - v nekem trenutku so se drugi udeleženci zbudili in prav tako želeli uporabiti Spark, vendar je bilo tam vse zasedeno in oni so bili nezadovoljni. Lahko jih je razumeti. Začeli smo pregledovati dokumentacijo. Izkazalo se je, da obstaja vrsta drugih parametrov, s katerimi lahko vplivamo na proces. Na primer, če je izvajalec v stanju pripravljenosti, po katerem času se mu lahko vzamejo sredstva?

spark.dynamicAllocation.executorIdleTimeout=120s

V našem primeru, če vaši izvršitelji dve minuti ne naredijo ničesar, potem jih vrnite v skupni bazen. Toda ta parameter ni bil vedno dovolj. Jasno je bilo, da oseba že dolgo ni počela ničesar, sredstva pa se niso sprostila. Izkazalo se je, da obstaja tudi poseben parameter - po katerem času izbrati izvajalce, ki vsebujejo predpomnjene podatke. Privzeto je bil ta parameter neskončnost! Popravili smo.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

Se pravi, če vaši izvršitelji 5 minut ne naredijo ničesar, jih dajte v skupni bazen. V tem načinu je hitrost sproščanja in izdajanja virov za veliko število uporabnikov postala spodobna. Količina nezadovoljstva se je zmanjšala. Vendar smo se odločili iti dlje in omejiti največje število izvajalcev na aplikacijo – v bistvu na udeleženca programa.

spark.dynamicAllocation.maxExecutors=19

Zdaj so seveda na drugi strani nezadovoljni - "grozd miruje, jaz pa imam samo 19 izvršiteljev," a kaj lahko, rabimo neko pravo ravnovesje. Ne moreš osrečiti vseh.

In še ena majhna zgodba, povezana s specifiko našega primera. Nekako je več ljudi zamujalo na praktični pouk in iz nekega razloga se Spark ni zagnal namesto njih. Pogledali smo količino brezplačnih virov - zdi se, da je tam. Spark bi se moral začeti. Na srečo je bila takrat dokumentacija že nekje dodana v podkorteks in spomnili smo se, da Spark ob zagonu išče vrata, na katerih bi začel. Če so prva vrata v območju zasedena, se premakne na naslednja po vrstnem redu. Če je brezplačen, zajema. In obstaja parameter, ki označuje največje število poskusov za to. Privzeto je 16. Število je manjše od števila ljudi v naši skupini v razredu. Skladno s tem je po 16 poskusih Spark obupal in rekel, da ne morem začeti. To nastavitev smo popravili.

spark.port.maxRetries=50

Nato vam bom povedal nekaj nastavitev, ki niso zelo povezane s posebnostmi našega primera.

Če želite hitreje zagnati Spark, priporočamo, da arhivirate mapo jars, ki se nahaja v domačem imeniku SPARK_HOME, in jo postavite na HDFS. Potem ne bo izgubljal časa z nalaganjem teh jarnikov s strani delavcev.

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

Za hitrejše delovanje je priporočljivo uporabljati kryo tudi kot serializator. Je bolj optimiziran kot privzeti.

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

In obstaja tudi dolgoletna težava s Sparkom, da se pogosto zruši iz spomina. Pogosto se to zgodi v trenutku, ko so delavci vse izračunali in rezultat poslali vozniku. Ta parameter smo povečali zase. Privzeto je 1 GB, mi pa 3.

spark.driver.maxResultSize=3072

In za konec še kot sladica. Kako posodobiti Spark na različico 2.1 v distribuciji HortonWorks - HDP 2.5.3.0. Ta različica HDP vsebuje vnaprej nameščeno različico 2.0, vendar smo se nekoč sami odločili, da se Spark precej aktivno razvija in da vsaka nova različica popravi nekaj napak in nudi dodatne funkcije, vključno z API-jem za python, zato smo se odločili, kaj je treba narediti je posodobitev.

Prenesli različico z uradne spletne strani za Hadoop 2.7. Razpakirali in dali v mapo HDP. Po potrebi smo namestili simbolne povezave. Zaženemo ga - ne zažene se. Napiše zelo čudno napako.

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

Po googlanju smo ugotovili, da se je Spark odločil, da ne bo čakal, da se rodi Hadoop, in se je odločil uporabiti novo različico dresa. Sami se med seboj prepirajo o tej temi v JIRI. Rešitev je bila prenos različica dresa 1.17.1. Postavite to v mapo jars v SPARK_HOME, znova stisnite in naložite v HDFS.

To napako smo zaobšli, pojavila pa se je nova in precej poenostavljena.

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

Hkrati poskušamo zagnati različico 2.0 - vse je v redu. Poskusite uganiti, kaj se dogaja. Pogledali smo v dnevnike te aplikacije in videli nekaj takega:

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

Na splošno se iz nekega razloga hdp.version ni razrešil. Po googlanju smo našli rešitev. Odpreti morate nastavitve YARN v Ambariju in tam dodati parameter na spletno mesto preje po meri:

hdp.version=2.5.3.0-37

Ta čarovnija je pomagala in Spark je vzletel. Preizkusili smo več naših prenosnikov Jupyter. Vse dela. Pripravljeni smo na prvo Spark lekcijo v soboto (jutri)!

DUP. Med poukom se je pojavil še en problem. Na neki točki je YARN prenehal zagotavljati vsebnike za Spark. V YARN je bilo treba popraviti parameter, ki je bil privzeto 0.2:

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

To pomeni, da je le 20% virov sodelovalo pri razdeljevanju sredstev. Po spremembi parametrov smo ponovno naložili YARN. Težava je bila odpravljena in tudi ostali udeleženci so lahko zagnali spark context.

Vir: www.habr.com

Dodaj komentar