Habr, hallo! Gisteren op , van de jongens van Rambler&Co, waren er nogal wat vragen van deelnemers met betrekking tot het configureren van deze tool. We besloten in zijn voetsporen te treden en onze ervaringen te delen. Het onderwerp is niet eenvoudig - dus we nodigen u uit om uw ervaringen in de reacties te delen, misschien begrijpen en gebruiken we ook iets verkeerds.
Een korte introductie over hoe we Spark gebruiken. We hebben een programma van drie maanden , en gedurende de tweede module werken onze deelnemers aan dit instrument. Dienovereenkomstig is het onze taak als organisatoren om het cluster voor te bereiden voor gebruik in een dergelijk geval.
Het bijzondere van ons gebruik is dat het aantal mensen dat tegelijkertijd aan Spark werkt gelijk kan zijn aan de hele groep. Bijvoorbeeld tijdens een seminar, wanneer iedereen iets tegelijkertijd probeert en na onze leraar herhaalt. En dit is niet veel - soms tot 40 personen. Er zijn waarschijnlijk niet veel bedrijven in de wereld die met een dergelijke use case te maken hebben.
Vervolgens zal ik u vertellen hoe en waarom we bepaalde configuratieparameters hebben geselecteerd.
Laten we vanaf het allereerste begin beginnen. Spark heeft 3 opties om op een cluster te draaien: standalone, met Mesos en met YARN. We hebben voor de derde optie gekozen, omdat deze voor ons logisch was. We hebben al een hadoop-cluster. Onze deelnemers zijn al goed bekend met de architectuur ervan. Laten we GAREN gebruiken.
spark.master=yarn
Verder interessanter. Elk van deze drie implementatieopties heeft twee implementatieopties: client en cluster. Gebaseerd en verschillende links op internet kunnen we concluderen dat de client geschikt is voor interactief werk, bijvoorbeeld via jupyter-notebook, en dat cluster meer geschikt is voor productieoplossingen. In ons geval waren we geΓ―nteresseerd in interactief werk, daarom:
spark.deploy-mode=client
Over het algemeen zal Spark vanaf nu op de een of andere manier aan YARN werken, maar dit was niet genoeg voor ons. Omdat we een programma over big data hebben, hadden de deelnemers soms niet genoeg van wat er werd verkregen binnen het raamwerk van een gelijkmatige verdeling van de middelen. En toen ontdekten we iets interessants: dynamische toewijzing van middelen. Kortom, het punt is dit: als je een moeilijke taak hebt en het cluster gratis is (bijvoorbeeld 's ochtends), dan kan Spark je met deze optie extra middelen geven. De noodzaak wordt daar berekend volgens een sluwe formule. We zullen niet in details treden: het werkt goed.
spark.dynamicAllocation.enabled=true
We hebben deze parameter ingesteld en bij het opstarten crashte Spark en startte niet. Dat klopt, want ik moest het lezen voorzichtiger. Er staat dat om alles in orde te maken, je ook een extra parameter moet inschakelen.
spark.shuffle.service.enabled=true
Waarom is het nodig? Als ons werk niet langer zoveel hulpbronnen vereist, moet Spark ze teruggeven aan de gemeenschappelijke voorraad. De meest tijdrovende fase in vrijwel elke MapReduce-taak is de Shuffle-fase. Met deze parameter kunt u de gegevens opslaan die in dit stadium worden gegenereerd en de uitvoerders dienovereenkomstig vrijgeven. En de uitvoerder is het proces dat alles over de werknemer berekent. Het heeft een bepaald aantal processorkernen en een bepaalde hoeveelheid geheugen.
Deze parameter is toegevoegd. Alles leek te werken. Het viel op dat deelnemers daadwerkelijk meer middelen kregen wanneer ze die nodig hadden. Maar er deed zich een ander probleem voor: op een gegeven moment werden andere deelnemers wakker en wilden ook Spark gebruiken, maar daar was alles druk en waren ze ongelukkig. Ze kunnen worden begrepen. We zijn begonnen met het bekijken van de documentatie. Het bleek dat er nog een aantal andere parameters zijn die kunnen worden gebruikt om het proces te beΓ―nvloeden. Als de uitvoerder zich bijvoorbeeld in de standby-modus bevindt, na welke tijd kunnen er dan bronnen uit worden gehaald?
spark.dynamicAllocation.executorIdleTimeout=120s
In ons geval, als uw executeurs-testamentairen twee minuten niets doen, breng ze dan terug naar de gemeenschappelijke pool. Maar deze parameter was niet altijd voldoende. Het was duidelijk dat de persoon al een hele tijd niets meer had gedaan en dat er geen middelen vrijkwamen. Het bleek dat er ook een speciale parameter is: na welke tijd moeten uitvoerders worden geselecteerd die gegevens in de cache bevatten. Standaard was deze parameter oneindig! Wij hebben het gecorrigeerd.
spark.dynamicAllocation.cachedExecutorIdleTimeout=600s
Dat wil zeggen, als uw executeurs-testamentairen gedurende 5 minuten niets doen, geef ze dan aan de gemeenschappelijke pool. In deze modus is de snelheid van het vrijgeven en uitgeven van bronnen voor een groot aantal gebruikers behoorlijk geworden. De hoeveelheid onvrede is afgenomen. Maar we besloten verder te gaan en het maximale aantal uitvoerders per applicatie te beperken, in essentie per programmadeelnemer.
spark.dynamicAllocation.maxExecutors=19
Nu zijn er natuurlijk ontevreden mensen aan de andere kant: "Het cluster is inactief en ik heb maar 19 executeurs-testamentairen", maar wat kun je doen? We hebben een soort correct evenwicht nodig. Je kunt niet iedereen blij maken.
En nog een klein verhaal over de specifieke kenmerken van onze zaak. Op de een of andere manier waren verschillende mensen te laat voor een praktijkles, en om de een of andere reden startte Spark niet voor hen. We hebben gekeken naar de hoeveelheid gratis middelen - het lijkt er te zijn. De vonk zou moeten starten. Gelukkig was de documentatie tegen die tijd al ergens aan de subcortex toegevoegd, en we herinnerden ons dat Spark bij de lancering een poort zoekt om mee te beginnen. Als de eerste poort in het bereik bezet is, wordt deze op volgorde naar de volgende verplaatst. Als het gratis is, vangt het op. En er is een parameter die het maximale aantal pogingen hiervoor aangeeft. De standaardwaarde is 16. Het aantal is kleiner dan het aantal mensen in onze groep in de klas. Dienovereenkomstig gaf Spark het na zestien pogingen op en zei dat ik niet kon starten. We hebben deze parameter gecorrigeerd.
spark.port.maxRetries=50
Vervolgens zal ik u vertellen over enkele instellingen die niet erg gerelateerd zijn aan de specifieke kenmerken van onze zaak.
Om Spark sneller te starten, wordt aanbevolen om de map jars in de thuismap SPARK_HOME te archiveren en op HDFS te plaatsen. Dan zal hij geen tijd verspillen met het laden van deze jarniks door arbeiders.
spark.yarn.archive=hdfs:///tmp/spark-archive.zip
Het wordt ook aanbevolen om kryo als serializer te gebruiken voor een snellere werking. Het is meer geoptimaliseerd dan de standaardversie.
spark.serializer=org.apache.spark.serializer.KryoSerializer
En er is ook een al lang bestaand probleem met Spark dat het vaak uit het geheugen crasht. Vaak gebeurt dit op het moment dat de arbeiders alles hebben berekend en het resultaat naar de chauffeur sturen. We hebben deze parameter voor onszelf groter gemaakt. Standaard is dit 1 GB, we hebben er 3 gemaakt.
spark.driver.maxResultSize=3072
En als laatste: als dessert. Spark bijwerken naar versie 2.1 op HortonWorks-distributie - HDP 2.5.3.0. Deze versie van HDP bevat een vooraf geΓ―nstalleerde versie 2.0, maar we hebben ooit voor onszelf besloten dat Spark behoorlijk actief aan het ontwikkelen is, en dat elke nieuwe versie een aantal bugs oplost en extra functies biedt, ook voor de Python API, dus we hebben besloten wat er moet gebeuren klaar is een update.
De versie gedownload van de officiΓ«le website voor Hadoop 2.7. Pak het uit en plaats het in de HDP-map. We hebben de symlinks indien nodig geΓ―nstalleerd. We lanceren het - het start niet. Schrijft een zeer onduidelijke fout.
java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig
Na googlen kwamen we erachter dat Spark besloot niet te wachten tot Hadoop geboren was, en besloot de nieuwe versie van jersey te gebruiken. Zelf gaan ze in JIRA met elkaar in discussie over dit onderwerp. De oplossing was downloaden . Plaats dit in de map jars in SPARK_HOME, zip het opnieuw en upload het naar HDFS.
We hebben deze fout kunnen omzeilen, maar er ontstond een nieuwe en tamelijk gestroomlijnde fout.
org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master
Tegelijkertijd proberen we versie 2.0 uit te voeren - alles is in orde. Probeer te raden wat er aan de hand is. We hebben de logboeken van deze applicatie bekeken en zagen zoiets als dit:
/usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jar
Over het algemeen werd hdp.version om de een of andere reden niet opgelost. Na wat googlen hebben we een oplossing gevonden. Je moet naar de YARN-instellingen in Ambari gaan en daar een parameter toevoegen aan de aangepaste garensite:
hdp.version=2.5.3.0-37
Deze magie hielp en Spark vertrok. We hebben verschillende van onze jupyter-laptops getest. Alles werkt. Wij zijn klaar voor de eerste Spark les aanstaande zaterdag (morgen)!
UPD. Tijdens de les kwam een ββander probleem aan het licht. Op een gegeven moment stopte YARN met het leveren van containers voor Spark. In YARN was het nodig om de parameter te corrigeren, die standaard 0.2 was:
yarn.scheduler.capacity.maximum-am-resource-percent=0.8
Dat wil zeggen dat slechts 20% van de middelen deelnam aan de verdeling van middelen. Nadat we de parameters hadden gewijzigd, hebben we YARN opnieuw geladen. Het probleem was opgelost en de rest van de deelnemers kon ook sparkcontext uitvoeren.
Bron: www.habr.com
