Een gids voor Apache Mesos

1. Overzicht

We implementeren meestal verschillende applicaties op hetzelfde cluster van machines. Het is tegenwoordig bijvoorbeeld gebruikelijk om een ​​gedistribueerde verwerkingsengine zoals Apache Spark of Apache Flink te hebben met gedistribueerde databases zoals Apache Cassandra in hetzelfde cluster.

Apache Mesos is een platform dat het mogelijk maakt om bronnen effectief te delen tussen dergelijke applicaties.

In dit artikel bespreken we eerst enkele problemen met de toewijzing van bronnen binnen toepassingen die op hetzelfde cluster zijn geïmplementeerd. Later zullen we zien hoe Apache Mesos zorgt voor een beter gebruik van bronnen tussen applicaties.

2. Het delen van het cluster

Veel applicaties moeten een cluster delen. Over het algemeen zijn er twee veel voorkomende benaderingen:

  • Partitioneer het cluster statisch en voer op elke partitie een applicatie uit
  • Wijs een set machines toe aan een applicatie

Hoewel deze benaderingen het mogelijk maken dat applicaties onafhankelijk van elkaar worden uitgevoerd, wordt er geen hoog resourcegebruik bereikt.

Overweeg bijvoorbeeld een applicatie die werkt slechts gedurende een korte periode, gevolgd door een periode van inactiviteit. Nu we statische machines of partities aan deze applicatie hebben toegewezen, hebben we dat gedaan ongebruikte middelen tijdens de inactieve periode.

We kunnen het gebruik van resources optimaliseren door vrije resources tijdens de inactieve periode opnieuw toe te wijzen aan andere applicaties.

Apache Mesos helpt bij de dynamische toewijzing van bronnen tussen applicaties.

3. Apache Mesos

Met beide benaderingen voor het delen van clusters die we hierboven hebben besproken, zijn applicaties zich alleen bewust van de bronnen van een bepaalde partitie of machine waarop ze draaien. Apache Mesos biedt echter een abstract overzicht van alle bronnen in het cluster voor toepassingen.

Zoals we binnenkort zullen zien, fungeert Mesos als een interface tussen machines en applicaties. Het biedt applicaties met de beschikbare bronnen op alle computers in het cluster. Het werkt deze informatie regelmatig bij om bronnen op te nemen die door toepassingen worden vrijgemaakt die de voltooiingsstatus hebben bereikt. Hierdoor kunnen applicaties de beste beslissing nemen over welke taak op welke machine moet worden uitgevoerd.

Laten we, om te begrijpen hoe Mesos werkt, eens kijken naar de architectuur:

Deze afbeelding maakt deel uit van de officiële documentatie voor Mesos (bron). Hier, Hadoop en MPI zijn twee applicaties die het cluster delen.

We zullen het hebben over elk onderdeel dat hier wordt getoond in de volgende paar secties.

3.1. Mesos-meester

Master is de kerncomponent in deze setup en slaat de huidige status van bronnen op in het cluster. Bovendien fungeert het als een orchestrator tussen de agents en de toepassingen door informatie door te geven over zaken als bronnen en taken.

Aangezien elke storing in de master resulteert in het verlies van de status van resources en taken, implementeren we deze in een configuratie met hoge beschikbaarheid. Zoals te zien is in het bovenstaande diagram, implementeert Mesos standby-master-daemons samen met één leider. Deze daemons vertrouwen op Zookeeper voor het herstellen van de status in geval van een storing.

3.2. Mesos-agenten

Een Mesos-cluster moet op elke machine een agent draaien. Deze agenten rapporteer hun bronnen periodiek aan de master en op zijn beurt, taken ontvangen die een toepassing heeft gepland om uit te voeren. Deze cyclus herhaalt zich nadat de geplande taak is voltooid of verloren is gegaan.

In de volgende secties zullen we zien hoe applicaties taken plannen en uitvoeren op deze agents.

3.3. Mesos Frameworks

Met Mesos kunnen applicaties een abstracte component implementeren die samenwerkt met de Master om ontvang de beschikbare bronnen in het cluster en bovendien planningsbeslissingen nemen gebaseerd op hen. Deze componenten staan ​​bekend als frameworks.

Een Mesos-raamwerk bestaat uit twee subcomponenten:

  • Planner - Hiermee kunnen applicaties taken plannen op basis van beschikbare bronnen op alle agenten
  • Uitvoerder - Draait op alle agents en bevat alle informatie die nodig is om een ​​geplande taak op die agent uit te voeren

Dit hele proces wordt afgebeeld met deze stroom:

Eerst rapporteren de agenten hun bronnen aan de master. Op dit moment biedt master deze bronnen aan alle geregistreerde planners. Dit proces staat bekend als een resource-aanbieding en we zullen het in de volgende sectie in detail bespreken.

De planner kiest vervolgens de beste agent en voert er verschillende taken op uit via de Master. Zodra de uitvoerder de toegewezen taak heeft voltooid, publiceren agenten hun bronnen opnieuw naar de master. Master herhaalt dit proces van het delen van bronnen voor alle frameworks in het cluster.

Mesos staat applicaties toe implementeren hun aangepaste planner en uitvoerder in verschillende programmeertalen. Een Java-implementatie van planner moet implementerende Planner koppel:

openbare klasse HelloWorldScheduler implementeert Scheduler {@Override public void registered (SchedulerDriver schedulerDriver, Protos.FrameworkID frameworkID, Protos.MasterInfo masterInfo) {} @Override public void opnieuw geregistreerd (SchedulerDriver schedulerDriver, Protos.MasterInfo masterInfo schedulerDriver, List list) {} @Override public void offerRescinded (SchedulerDriver schedulerDriver, OfferID offerID) {} @Override public void statusUpdate (SchedulerDriver schedulerDriver, Protos.TaskStatus taskStatus) {} @Override public void frameworkMessage, Protos.TaskStatus taskStatus) , Protos.SlaveID slaveID, byte [] bytes) {} @Override public void verbroken (SchedulerDriver schedulerDriver) {} @Override public void slaveLost (SchedulerDriver schedulerDriver, Protos.SlaveID slaveID) {} @Override public void executorLost (SchedulerDriver, plannerLost .ExecutorID executorID, Protos.SlaveID slaveID, i nt i) {} @Override public void error (SchedulerDriver schedulerDriver, String s) {}}

Zoals te zien is, bestaat het voornamelijk uit verschillende callback-methoden voor communicatie met de master vooral.

Evenzo moet de implementatie van een uitvoerder het Uitvoerder koppel:

public class HelloWorldExecutor implementeert Executor {@Override public void geregistreerd (ExecutorDriver driver, Protos.ExecutorInfo executorInfo, Protos.FrameworkInfo frameworkInfo, Protos.SlaveInfo slaveInfo) {} @Override public void opnieuw geregistreerd (ExecutorDriver @ driver, Protos.SlaveO slaveInforide) {} public void verbroken (ExecutorDriver-stuurprogramma) {} @Override public void launchTask (ExecutorDriver-stuurprogramma, Protos.TaskInfo-taak) {} @Override public void killTask ​​(ExecutorDriver-stuurprogramma, Protos.TaskID taskId) {} ​​@Override public void frameworkMessage (ExecutorDriver-stuurprogramma, byte [] data) {} @Override public void shutdown (ExecutorDriver-stuurprogramma) {}}

We zullen een operationele versie van de planner en uitvoerder in een later gedeelte zien.

4. Beheer van middelen

4.1. Aanbiedingen van bronnen

Zoals we eerder hebben besproken, publiceren agenten hun broninformatie naar de master. De master biedt deze bronnen op zijn beurt aan aan de frameworks die in het cluster worden uitgevoerd. Dit proces staat bekend als een resource aanbieding.

Een resource-aanbieding bestaat uit twee delen: resources en attributen.

Middelen zijn gewend hardware-informatie van de agentmachine publiceren zoals geheugen, CPU en schijf.

Er zijn vijf vooraf gedefinieerde bronnen voor elke agent:

  • processor
  • gpu
  • mem
  • schijf
  • poorten

De waarden voor deze bronnen kunnen worden gedefinieerd in een van de drie typen:

  • Scalair - Wordt gebruikt om numerieke informatie weer te geven met behulp van drijvende-kommagetallen om breuken mogelijk te maken, zoals 1,5 G geheugen
  • Bereik - Wordt gebruikt om een ​​reeks scalaire waarden weer te geven, bijvoorbeeld een poortbereik
  • Set - Wordt gebruikt om meerdere tekstwaarden weer te geven

Standaard probeert de Mesos-agent deze bronnen van de machine te detecteren.

In sommige situaties kunnen we echter aangepaste bronnen op een agent configureren. De waarden voor dergelijke aangepaste bronnen moeten opnieuw in een van de hierboven besproken typen zijn.

We kunnen onze agent bijvoorbeeld starten met deze middelen:

--resources = 'cpus: 24; gpus: 2; mem: 24576; schijf: 409600; poorten: [21000-24000,30000-34000]; bugs (debug_role): {a, b, c}'

Zoals u kunt zien, hebben we de agent geconfigureerd met enkele van de vooraf gedefinieerde bronnen en één aangepaste bron met de naam bugs welke is van set type.

Naast resources kunnen agenten sleutelwaardeattributen naar de master publiceren. Deze attributen fungeren als aanvullende metadata voor de agent en helpen raamwerken bij het plannen van beslissingen.

Een handig voorbeeld kan zijn voeg agenten toe aan verschillende rekken of zones en dan plan verschillende taken op hetzelfde rack of dezelfde zone om datalocaliteit te bereiken:

--attributes = 'rack: abc; zone: west; os: centos5; level: 10; keys: [1000-1500]'

Net als bij resources kunnen waarden voor attributen een scalair, een bereik of een teksttype zijn.

4.2. Resource-rollen

Veel moderne besturingssystemen ondersteunen meerdere gebruikers. Op dezelfde manier ondersteunt Mesos ook meerdere gebruikers in hetzelfde cluster. Deze gebruikers staan ​​bekend als rollen. We kunnen elke rol beschouwen als een resourceconsument binnen een cluster.

Hierdoor kunnen Mesos-agenten de bronnen onder verschillende rollen verdelen op basis van verschillende toewijzingsstrategieën. Bovendien kunnen frameworks zich abonneren op deze rollen binnen het cluster en hebben ze een fijnmazige controle over bronnen onder verschillende rollen.

Beschouw bijvoorbeeld een clusterhostingstoepassingen die verschillende gebruikers bedienen in een organisatie. Dus door Door de resources in rollen te verdelen, kan elke applicatie geïsoleerd werken van een ander.

Bovendien kunnen frameworks deze rollen gebruiken om gegevenslocatie te bereiken.

Stel dat we twee applicaties hebben in het cluster met de naam producent en klant. Hier, producent schrijft gegevens naar een persistent volume dat klant kan achteraf lezen. We kunnen de klant applicatie door het volume te delen met de producent.

Omdat Mesos meerdere applicaties toestaat om zich op dezelfde rol te abonneren, kunnen we het persistente volume aan een resourcerol koppelen. Verder de kaders voor beide producent en klant zullen beide zich abonneren op dezelfde resource-rol. Daarom, de klant de toepassing kan nu de taak voor het lezen van gegevens starten op hetzelfde volume als de producent toepassing.

4.3. Reservering van middelen

Nu kan de vraag rijzen hoe Mesos clusterbronnen aan verschillende rollen toewijst. Mesos wijst de middelen toe door middel van reserveringen.

Er zijn twee soorten reserveringen:

  • Statische reservering
  • Dynamische reservering

Statische reservering is vergelijkbaar met de resourcetoewijzing bij het opstarten van de agent die we in de eerdere secties hebben besproken:

 --resources = "cpus: 4; mem: 2048; cpus (baeldung): 8; mem (baeldung): 4096"

Het enige verschil hier is dat nu de Mesos-agent reserveert acht CPU's en 4096m geheugen voor de genoemde rol baeldung.

Dynamische reservering stelt ons in staat om de bronnen binnen rollen te herschikken, in tegenstelling tot de statische reservering. Met Mesos kunnen frameworks en clusteroperators de toewijzing van bronnen dynamisch wijzigen via framework-berichten als reactie op het aanbod van bronnen of via HTTP-eindpunten.

Mesos wijst alle bronnen zonder enige rol toe aan een standaardrol genaamd (*). Master biedt dergelijke middelen aan alle frameworks aan, of ze er nu wel of niet op zijn geabonneerd.

4.4. Gewichten en quota van middelen

Over het algemeen biedt de Mesos-master middelen aan met behulp van een eerlijkheidsstrategie. Het gebruikt de gewogen Dominant Resource Fairness (wDRF) om de rollen te identificeren die onvoldoende middelen hebben. De master biedt dan meer bronnen aan voor de frameworks die zich hebben aangemeld voor deze rollen.

Hoewel het eerlijk delen van bronnen tussen applicaties een belangrijk kenmerk van Mesos is, is het niet altijd nodig. Stel dat een cluster applicaties host die een lage resource footprint hebben, samen met applicaties die een hoge resourcevraag hebben. Bij dergelijke implementaties zouden we middelen willen toewijzen op basis van de aard van de applicatie.

Mesos staat frameworks toe vraag meer middelen door u te abonneren op rollen en een hogere gewichtswaarde toe te voegen aan die rol. Daarom als er twee rollen zijn, een met gewicht 1 en een andere met gewicht 2, zal Mesos twee keer zoveel middelen toewijzen aan de tweede rol.

Net als bij resources kunnen we gewichten configureren via HTTP-eindpunten.

Naast het zorgen voor een eerlijk deel van de middelen voor een rol met gewichten, zorgt Mesos daar ook voor de minimale middelen voor een rol worden toegewezen.

Mesos staat ons toe quota toevoegen aan de resourcerollen. Een quotum specificeert het minimale aantal middelen dat een rol gegarandeerd ontvangt.

5. Uitvoeringskader

Zoals we in een eerdere sectie hebben besproken, staat Mesos toe dat applicaties framework-implementaties bieden in een taal naar keuze. In Java wordt een raamwerk geïmplementeerd met behulp van de hoofdklasse - die fungeert als een ingangspunt voor het raamwerkproces - en de implementatie van Planner en Uitvoerder eerder besproken.

5.1. Framework Hoofdklasse

Voordat we een planner en een uitvoerder implementeren, implementeren we eerst het toegangspunt voor ons framework dat:

  • Registreert zich bij de master
  • Levert runtime-informatie van de uitvoerder aan agenten
  • Start de planner

We zullen eerst een Maven-afhankelijkheid voor Mesos toevoegen:

 org.apache.mesos mesos 0.28.3 

Vervolgens implementeren we het HelloWorldMain voor ons kader. Een van de eerste dingen die we zullen doen, is het executor-proces starten op de Mesos-agent:

public static void main (String [] args) {String path = System.getProperty ("user.dir") + "/target/libraries2-1.0.0-SNAPSHOT.jar"; CommandInfo.URI uri = CommandInfo.URI.newBuilder (). SetValue (pad) .setExtract (false) .build (); String helloWorldCommand = "java -cp bibliotheken2-1.0.0-SNAPSHOT.jar com.baeldung.mesos.executors.HelloWorldExecutor"; CommandInfo commandInfoHelloWorld = CommandInfo.newBuilder () .setValue (helloWorldCommand) .addUris (uri) .build (); ExecutorInfo executorHelloWorld = ExecutorInfo.newBuilder () .setExecutorId (Protos.ExecutorID.newBuilder () .setValue ("HelloWorldExecutor")) .setCommand (commandInfoHelloWorld) .setName ("Hallo Wereld (Java)"). "SetSource. (" Java) ")." bouwen(); }

Hier hebben we eerst de binaire locatie van de uitvoerder geconfigureerd. Mesos-agent zou dit binaire bestand downloaden na framework-registratie. Vervolgens voert de agent het gegeven commando uit om het executor-proces te starten.

Vervolgens initialiseren we ons framework en starten we de planner:

FrameworkInfo.Builder frameworkBuilder = FrameworkInfo.newBuilder () .setFailoverTimeout (120000) .setUser ("") .setName ("Hello World Framework (Java)"); frameworkBuilder.setPrincipal ("test-framework-java"); MesosSchedulerDriver-stuurprogramma = nieuwe MesosSchedulerDriver (nieuwe HelloWorldScheduler (), frameworkBuilder.build (), args [0]);

Tenslotte, we zullen de MesosSchemaBestuurder die zichzelf registreert bij de Master. Voor een succesvolle registratie moeten we het IP-adres van de Master doorgeven als een programma-argument args [0] naar deze hoofdklasse:

int status = driver.run () == Protos.Status.DRIVER_STOPPED? 0: 1; driver.stop (); System.exit (status);

In de hierboven getoonde klas, CommandInfo, ExecutorInfo, en FrameworkInfo zijn allemaal Java-representaties van protobuf-berichten tussen master en frameworks.

5.2. Implementeren van Scheduler

Sinds Mesos 1.0, we kunnen het HTTP-eindpunt vanuit elke Java-applicatie aanroepen om berichten naar de Mesos-master te verzenden en te ontvangen. Sommige van deze berichten omvatten bijvoorbeeld raamwerkregistratie, aanbiedingen van bronnen en afwijzingen van aanbiedingen.

Voor Mesos 0.28 of eerder, we moeten de Planner koppel:

Voor het grootste deel zullen we ons alleen concentreren op de resourceOffers methode van de Planner. Laten we eens kijken hoe een planner bronnen ontvangt en taken op basis daarvan initialiseert.

Eerst zullen we zien hoe de planner middelen toewijst voor een taak:

@Override public void resourceOffers (SchedulerDriver schedulerDriver, lijstlijst) {for (Aanbieding aanbieding: lijst) {lijsttaken = nieuwe ArrayList (); Protos.TaskID taskId = Protos.TaskID.newBuilder () .setValue (Integer.toString (gelanceerdTasks ++)). Build (); System.out.println ("Start printHelloWorld" + taskId.getValue () + "Hallo wereld Java"); Protos.Resource.Builder cpus = Protos.Resource.newBuilder () .setName ("cpus") .setType (Protos.Value.Type.SCALAR) .setScalar (Protos.Value.Scalar.newBuilder () .setValue (1)) ; Protos.Resource.Builder mem = Protos.Resource.newBuilder () .setName ("mem") .setType (Protos.Value.Type.SCALAR) .setScalar (Protos.Value.Scalar.newBuilder () .setValue (128)) ;

Hier hebben we 1 CPU en 128 MB geheugen toegewezen voor onze taak. Vervolgens gebruiken we de Scheduler Driver om de taak op een agent te starten:

 TaskInfo printHelloWorld = TaskInfo.newBuilder () .setName ("printHelloWorld" + taskId.getValue ()) .setTaskId (taskId) .setSlaveId (offer.getSlaveId ()) .addResources (cpus) .addResources (memsetor). newBuilder (helloWorldExecutor)) .build (); List offerIDS = nieuwe ArrayList (); offerIDS.add (offer.getId ()); taken.add (printHelloWorld); schedulerDriver.launchTasks (offerIDS, taken); }}

Alternatief, Planner vindt vaak de noodzaak om aanbiedingen van middelen af ​​te wijzen. Als het Planner kan geen taak op een agent starten vanwege een gebrek aan middelen, het moet dat aanbod onmiddellijk afwijzen:

schedulerDriver.declineOffer (offer.getId ());

5.3. Implementeren Uitvoerder

Zoals we eerder hebben besproken, is de executor-component van het framework verantwoordelijk voor het uitvoeren van applicatietaken op de Mesos-agent.

We hebben de HTTP-eindpunten gebruikt voor de implementatie Planner in Mesos 1.0. Evenzo kunnen we het HTTP-eindpunt gebruiken voor de uitvoerder.

In een eerdere sectie hebben we besproken hoe een framework een agent configureert om het executor-proces te starten:

java -cp bibliotheken2-1.0.0-SNAPSHOT.jar com.baeldung.mesos.executors.HelloWorldExecutor

Met name dit commando houdt rekening met HalloWorldExecutor als de hoofdklasse. We zullen dit implementeren hoofd methode om initialiseer het MesosExecutorDriver die verbinding maakt met Mesos-agenten om taken te ontvangen en andere informatie te delen, zoals taakstatus:

publieke klasse HelloWorldExecutor implementeert Executor {public static void main (String [] args) {MesosExecutorDriver driver = nieuwe MesosExecutorDriver (nieuwe HelloWorldExecutor ()); System.exit (driver.run () == Protos.Status.DRIVER_STOPPED? 0: 1); }}

Het laatste dat u nu moet doen, is taken uit het raamwerk accepteren en ze op de agent starten. De informatie om een ​​taak te starten staat op zichzelf in het HelloWorldExecutor:

openbare ongeldige launchTask (ExecutorDriver-stuurprogramma, TaskInfo-taak) {Protos.TaskStatus-status = Protos.TaskStatus.newBuilder () .setTaskId (task.getTaskId ()) .setState (Protos.TaskState.TASK_RUNNING) .build (); driver.sendStatusUpdate (status); System.out.println ("Taak uitvoeren !!!"); status = Protos.TaskStatus.newBuilder () .setTaskId (task.getTaskId ()) .setState (Protos.TaskState.TASK_FINISHED) .build (); driver.sendStatusUpdate (status); }

Dit is natuurlijk slechts een eenvoudige implementatie, maar het legt uit hoe een uitvoerder in elke fase de taakstatus deelt met de master en vervolgens de taak uitvoert voordat een voltooiingsstatus wordt verzonden.

In sommige gevallen kunnen uitvoerders ook gegevens terugsturen naar de planner:

String myStatus = "Hallo Framework"; driver.sendFrameworkMessage (myStatus.getBytes ());

6. Conclusie

In dit artikel hebben we het delen van bronnen tussen toepassingen die in hetzelfde cluster worden uitgevoerd, kort besproken. We hebben ook besproken hoe Apache Mesos applicaties helpt een maximale benutting te bereiken met een abstract beeld van de clusterbronnen zoals CPU en geheugen.

Later bespraken we de dynamische toewijzing van bronnen tussen applicaties gebaseerd op verschillende fairness-beleidslijnen en -rollen. Mesos maakt het mogelijk om applicaties te maken planningsbeslissingen op basis van resource-aanbiedingen van Mesos-agenten in het cluster.

Ten slotte zagen we een implementatie van het Mesos-framework in Java.

Zoals gewoonlijk zijn alle voorbeelden beschikbaar op GitHub.