Habr, pĂ«rshĂ«ndetje! Dje nĂ« , nga djemtĂ« e Rambler&Co, kishte mjaft pyetje nga pjesĂ«marrĂ«sit lidhur me konfigurimin e kĂ«tij instrumenti. VendosĂ«m qĂ«, nĂ« kĂ«to gjurmĂ«, tĂ« ndajmĂ« pĂ«rvojĂ«n tonĂ«. Tema nuk Ă«shtĂ« e lehtĂ« â ndaj ofrojmĂ« tĂ« ndajmĂ« pĂ«rvojĂ«n gjithashtu nĂ« komentet, ndoshta ne gjithashtu nuk kuptojmĂ« ndonjĂ« gjĂ« siç duhet.
NjĂ« hyrje e vogĂ«l â si ne pĂ«rdorim Spark. Ne kemi njĂ« program tre-mujor , dhe gjithĂ« moduli i dytĂ«, pjesĂ«marrĂ«sit tanĂ« punojnĂ« me kĂ«tĂ« instrument. Ndaj, detyra jonĂ« si organizatorĂ« Ă«shtĂ« tĂ« pĂ«rgatisim njĂ« klaster pĂ«r pĂ«rdorim nĂ« kuadĂ«r tĂ« njĂ« rasti tĂ« tillĂ«.
Karakteristika e pĂ«rdorimit tonĂ« Ă«shtĂ« se numri i njerĂ«zve qĂ« punojnĂ« njĂ«kohĂ«sisht nĂ« Spark mund tĂ« jetĂ« i barabartĂ« me gjithĂ« grupin. PĂ«r shembull, nĂ« njĂ« seminar, kur tĂ« gjithĂ« provon njĂ« gjĂ« njĂ«kohĂ«sisht dhe pĂ«rsĂ«risin pas mĂ«suesit tonĂ«. Dhe kjo Ă«shtĂ« pak shumĂ« â deri nĂ« 40 njerĂ«z ndonjĂ«herĂ«. Ndoshta, nuk ka shumĂ« kompani nĂ« botĂ« qĂ« ballafaqohen me njĂ« skenar tĂ« tillĂ« pĂ«rdorimi.
Më tej do të flas për mënyrat dhe arsyet se si i përzgjodhëm këto parametro të konfigurimit.
Të fillojmë nga fillimi. Spark ka 3 mënyra për të punuar në një klaster: standalone, duke përdorur Mesos dhe duke përdorur YARN. Ne vendosëm të zgjidhim opsionin e tretë, sepse ishte logjike për ne. Ne tashmë kemi një klaster Hadoop. Pjesëtarët tanë janë të njohur me arkitekturën e tij. Le ta përdorim YARN.
spark.master=yarnMĂ« pas bĂ«het mĂ« interesante. Ădo njĂ« nga kĂ«to 3 opsione pĂ«r shpĂ«rndarje ka 2 mĂ«nyra pĂ«r deploy: client dhe cluster. Nga dhe lidhjet e ndryshme nĂ« internet, mund tĂ« arrihet nĂ« pĂ«rfundimin se client Ă«shtĂ« i pĂ«rshtatshĂ«m pĂ«r punĂ« interaktive â pĂ«r shembull, pĂ«rmes jupyter notebook, ndĂ«rsa cluster Ă«shtĂ« mĂ« i pĂ«rshtatshĂ«m pĂ«r zgjidhjet nĂ« prodhim. NĂ« rastin tonĂ«, na interesonte puna interaktive, kĂ«shtu qĂ«:
spark.deploy-mode=clientNĂ« parim, qĂ« nga ky moment, Spark do tĂ« funksionojĂ« nĂ« YARN, por kjo nuk ishte e mjaftueshme pĂ«r ne. Duke qenĂ« se kemi njĂ« program pĂ«r tĂ« dhĂ«na tĂ« mĂ«dha, ndonjĂ«herĂ« pjesĂ«marrĂ«sve u mungonte gjithçka qĂ« mund tĂ« arrihej pĂ«rmes ndarjes sĂ« barabartĂ« tĂ« burimeve. Dhe kĂ«tu gjetĂ«m njĂ« gjĂ« interesante â alokimin dinamik tĂ« burimeve. NĂ« pĂ«rmbledhje, thelbi Ă«shtĂ« ky: nĂ«se keni njĂ« detyrĂ« tĂ« rĂ«ndĂ« dhe klasteri Ă«shtĂ« i lirĂ« (p.sh., nĂ« mĂ«ngjes), atĂ«herĂ« me kĂ«tĂ« opsion Spark mund t'ju japĂ« burime shtesĂ«. Nevoja llogaritet atje sipas njĂ« formule interesante. Nuk do tĂ« hyjmĂ« nĂ« detaje â ajo funksionon mjaft mirĂ«.
spark.dynamicAllocation.enabled=trueNe e vendosëm këtë parameter, dhe kur e ekzekutuam Spark, u ankuar dhe nuk nisi. E drejtë, sepse duhej të lexohej më me kujdes. Aty tregohet se për të pasur gjithçka në rregull, duhet të aktivizohet edhe një parameter shtesë.
spark.shuffle.service.enabled=truePër çfarë është e nevojshme? Kur puna jonë nuk kërkon më aq shumë burime, Spark duhet t'i kthejë ato në rezervën e përgjithshme. Faza më e pun intensive në pothuajse çdo detyrë MapReduce është faza Shuffle. Ky parametr lejon ruajtjen e të dhënave që krijohen në këtë fazë dhe, për pasojë, lirimin e executors. Një executor është procesi që llogarit gjithçka në punë. Ai ka një numër të caktuar bërthamash procesori dhe një sasi të caktuar memories.
E kemi shtuar kĂ«tĂ« parametr. TĂ« gjitha duket se funksionojnĂ«. Ka filluar tĂ« vĂ«rehet se pjesĂ«marrĂ«sit realisht po merrnin mĂ« shumĂ« burime kur ishin tĂ« nevojshme. Por u shfaq njĂ« problem tjetĂ«r â nĂ« njĂ« moment tĂ« caktuar pjesĂ«marrĂ«sit e tjerĂ« u zgjuan dhe gjithashtu donin tĂ« pĂ«rdorin Spark, por ajo ishte e mbushur, dhe ata ishin tĂ« pakĂ«naqur. Mund tâi kuptojmĂ«. Filluam tĂ« shohim dokumentacionin. Aty dolĂ«n se kishte edhe disa parametra tĂ« tjerĂ« qĂ« mund tĂ« ndikojnĂ« nĂ« proces. PĂ«r shembull, nĂ«se executor Ă«shtĂ« nĂ« modalitetin e pritjes â pas sa kohĂ«sh mund tâi merret burimet?
spark.dynamicAllocation.executorIdleTimeout=120sNĂ« rastin tonĂ« â nĂ«se executorĂ«t tuaj nuk bĂ«jnĂ« asgjĂ« pĂ«r dy minuta, ju lutemi, ktheni ata nĂ« rezervĂ«n e pĂ«rbashkĂ«t. Por as ky parametĂ«r nuk ishte gjithmonĂ« i mjaftueshĂ«m. Ishte e qartĂ« se njĂ« person nuk po bĂ«nte asgjĂ« prej kohĂ«sh, por burimet nuk po liroheshin. Doli se kishte edhe njĂ« parametĂ«r tĂ« veçantĂ« â pas sa kohĂ«sh tĂ« merreshin executorĂ«t qĂ« kishin tĂ« dhĂ«na tĂ« ruajtura nĂ« cache. Nga parazgjedhja, ky parametĂ«r ishte vendosur nĂ« â pafundĂ«si! Ne e rregulluam atĂ«.
spark.dynamicAllocation.cachedExecutorIdleTimeout=600sKĂ«shtu qĂ«, nĂ«se pĂ«r 5 minuta executorĂ«t tuaj nuk bĂ«jnĂ« asgjĂ«, ktheni ata nĂ« rezervĂ«n e pĂ«rbashkĂ«t. NĂ« kĂ«tĂ« mĂ«nyrĂ«, shpejtĂ«sia e lirimit dhe ndarjes sĂ« burimeve pĂ«r njĂ« numĂ«r tĂ« madh pĂ«rdoruesish ka marrĂ« njĂ« nivel tĂ« kĂ«naqshĂ«m. Numri i pakĂ«naqĂ«sive u ul. Por ne vendosĂ«m tĂ« shkojmĂ« mĂ« tej dhe ta kufizojmĂ« numrin maksimal tĂ« executorĂ«ve pĂ«r njĂ« aplikacion â nĂ« thelb pĂ«r njĂ« pjesĂ«marrĂ«s tĂ« programit.
spark.dynamicAllocation.maxExecutors=19Tani, natyrisht, u shfaqĂ«n pakĂ«naqĂ«si nga ana tjetĂ«r â âklistri po pushon, ndĂ«rsa unĂ« kam vetĂ«m 19 executorĂ«â, por çfarĂ« mund tĂ« bĂ«jmĂ« â duhet njĂ« balancim i duhur. Nuk do tĂ« arrijmĂ« tĂ« bĂ«jmĂ« tĂ« gjithĂ« tĂ« lumtur.
Dhe njĂ« histori e vogĂ«l tjetĂ«r e lidhur me specifikat e rastit tonĂ«. NjĂ«herĂ« disa njerĂ«z vonuan nĂ« njĂ« nga ushtrimet praktike, dhe pĂ«r njĂ« arsye, Spark nuk u nis. Ne e kontrolluam numrin e burimeve tĂ« lira â duke dukur, kishte. Spark duhet tĂ« niste. FatmirĂ«sisht, nĂ« atĂ« kohĂ« dokumentacioni ishte tashmĂ« ndarĂ« nĂ« nĂ«nndĂ«rgjegje, dhe ne pĂ«rmendĂ«m se kur niset Spark, ai kĂ«rkon njĂ« port pĂ«r t'u nisur. NĂ«se porta e parĂ« nga diapazoni Ă«shtĂ« e zĂ«nĂ«, ai kalon nĂ« portin tjetĂ«r nĂ« rend. NĂ«se ai Ă«shtĂ« i lirĂ«, ai e kap. Dhe ka njĂ« parametĂ«r qĂ« tregon numrin maksimal tĂ« pĂ«rpjekjeve pĂ«r kĂ«tĂ«. NĂ« mĂ«nyrĂ« tĂ« paracaktuar, kjo Ă«shtĂ« 16. Numri Ă«shtĂ« mĂ« i vogĂ«l se njerĂ«zit nĂ« grupin tonĂ« gjatĂ« ushtrimit. Prandaj, pas 16 pĂ«rpjekjeve Spark e ndaloi atĂ« dhe tha se nuk mund tĂ« nisa. Ne e rregulluam kĂ«tĂ« parametĂ«r.
spark.port.maxRetries=50Më tutje do të tregoj disa konfigurime, që tashmë nuk janë shumë të lidhura me specifikat e rastit tonë.
Për një nisje më të shpejtë të Spark, ekziston një rekomandim për të kompresuar folderin jars, që ndodhet në direktorinë shtëpiake SPARK_HOME, dhe ta vendosni në HDFS. Kështu ai nuk do ta humbasë kohën në ngarkimin e këtyre jar-ve për punëtorët.
spark.yarn.archive=hdfs:///tmp/spark-archive.zipPo ashtu, për një funksionim më të shpejtë, rekomandohet të përdorni kryo si serializues. Ai është më i optimizuar se ai që është parazgjedhur.
spark.serializer=org.apache.spark.serializer.KryoSerializerDhe ka një problem të njohur me Spark, që shpesh përben probleme me memorie. Kjo ndodh shpesh kur punëtorët kanë përfunduar të gjitha llogaritjet dhe dërgojnë rezultatet te drejtuesi. Ne e vendosëm këtë parametr më të lartë. Kështu, parazgjedhja është 1Gb, ne e bëmë 3.
spark.driver.maxResultSize=3072Dhe e fundit, si njĂ« Ă«mbĂ«lsirĂ«. Si ta pĂ«rditĂ«sojmĂ« Spark nĂ« versionin 2.1 nĂ« distribucionin HortonWorks â HDP 2.5.3.0. Ky version HDP pĂ«rmban njĂ« version tĂ« parazgjedhur 2.0, por ne herĂ«n e parĂ« vendosĂ«m se Spark po zhvillohej vaĆŸhdimisht, dhe çdo version i ri rregullon disa defekte dhe jep mundĂ«si tĂ« reja, pĂ«rfshirĂ« edhe pĂ«r API-nĂ« python, kĂ«shtu qĂ« vendosĂ«m ta bĂ«jmĂ« pĂ«rditĂ«simin.
E kemi shkarkuar versionin nga faqja zyrtare pĂ«r Hadoop 2.7. E kemi shpĂ«rngulur, e kemi vendosur nĂ« dosjen me HDP. Kemi vendosur simoling si duhet. E nisim â nuk fillon. Shfaq njĂ« gabim shumĂ« tĂ« paqartĂ«.
java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfigPas duke kërkuar në Google, që e kuptuam se Spark vendosi të mos priste që Hadoop të zgjidhte problemin dhe vendosi të përdorte versionin e ri të jersey. Ata vetë po grindeshin për këtë çështje në JIRA. Zgjidhja ishte - shkarko . Vëzhgoje këtë në dosjen jars në SPARK_HOME, përsëri bëj zip dhe dërgoje në HDFS.
Ne e anashaluam këtë gabim, por lind një e re dhe mjaft e paqartë.
org.apache.spark.SparkException: Aplikimi Yarn ka përfunduar tashmë! Mund të ketë qenë i vrarë ose i paaftë për të nisur masterin e aplikacionit.Në këtë rast, po provojmë të lançojmë versionin 2.0 - gjithçka është në rregull. Provo të gjesh se çfarë ndodh. Ne shkuam në log-et e këtij aplikacioni dhe pamë diçka të tillë:
/usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jarNë përgjithësi, për ndonjë arsye, hdp.version nuk u zgjodh. Pas kërkimeve, gjetëm zgjidhjen. Duhet të hysh në Ambari, në cilësimet e YARN dhe të shtosh atje një parametër në yarn-site-n e personalizuar:
hdp.version=2.5.3.0-37Kjo magji ndihmoi, dhe Spark fluturoi. Testuam disa nga jupyter-notebook-et tona. Ădo gjĂ« funksionon. Jemi gati pĂ«r sesionin e parĂ« pĂ«r Spark tĂ« shtunĂ«n (nĂ« ditĂ«n e nesĂ«rme)!
UPD. Gjatë sesionit doli një problem tjetër. Në një moment, YARN ndaloi së dhëni konteinerë për Spark. Duhej të rregullohej një parametër në YARN, i cili nga default ishte 0.2:
yarn.scheduler.capacity.maximum-am-resource-percent=0.8 Do të thotë se vetëm 20% e burimeve morën pjesë në shpërndarjen e burimeve. Duke ndryshuar parametrat, e ngarkuam përsëri YARN. Problemi u zgjidh dhe pjesëmarrësit e tjerë arritën gjithashtu të aktivizojnë kontekstin e spark.
Burimi: habr.com
