Follow Us on Twitter

Grid computing clusters als platform voor microservices architectuur

September 2016 - De software-wereld is altijd in beweging. Applicaties worden steeds minder als grote monolieten gebouwd. Service Oriented Architecture is al bijna weer passé dus het wordt tijd voor een nieuwe architectuur. Microservices architectuur is al een tijdje helemaal hip. Weg van de monoliet en zo klein mogelijke componentjes maken (de microservices). Door kleine componenten te maken zijn deze een stuk eenvoudiger dan een monolithische applicatie met vergelijkbare functionaliteit.

Waar de individuele microservices een stuk simpeler zijn is de infrastructuur (het platform) weer complexer want dat moet de verschillende microservices aan elkaar knopen, zorgen dat alle microservices aanstaan (vaak zelfs meerdere parallelle instanties), en dat deze elkaar kunnen bereiken.

Een ander interessant fenomeen is grid computing, het groeperen van servers in clusters (grids) die complexe zware taken verdelen over de servers in het cluster. Vele handen maken nu eenmaal licht werk.

In dit Whitebook wordt een praktisch voorbeeld gegeven van een microservices architectuur die een grid computing cluster gebruikt als platform. Door de kleine services in een cluster te plaatsen kan een groot deel van de complexiteit van de infrastructuur belegd worden in het cluster. Veel clusters hebben goede management mogelijkheden waardoor het onderhouden van een complexe set microservices ineens veel eenvoudiger wordt. Ook de beschikbaarheid van gedeelde resources maakt het eenvoudig dat meerdere instanties van dezelfde service parallel werken.

Wat is microservices architectuur?

Zoals eerder genoemd gaat microservices architectuur over het maken van een serie gekoppelde mini-applicaties die gezamenlijk dezelfde functionaliteit hebben als een monolithische applicatie.

Over het algemeen heeft elke microservice één specifieke taak. In het geval van een e-commerce systeem zou er bijvoorbeeld een front-end voor gebruikers kunnen zijn en microservices voor voorraadbeheer, facturatie en voor verzending.

Microservices Architectuur
Figuur 1: Applicatie met 3 microservices

Microservices hebben ook een voordeel bij installatie. De losse microservices kunnen (dynamisch) verdeeld worden over een serie servers. Zo kan een goede balans gevonden worden dat die microservices die intensief gebruikt worden (of veel vergen van de servers) op meer servers staan dan de microservices die niet zoveel gebruikt worden (of weinig vergen van de servers). Dit vergt uiteraard wel dat de microservices die op meerdere servers beschikbaar zijn ook parallelliseerbaar zijn.

Zoals elke architectuur heeft microservices architectuur ook zijn nadelen. De complexiteit verschuift grotendeels van de software componenten naar de onderliggende infrastructuur. Het beheersen van een applicatie die opgebouwd is uit microservices is een stuk complexer door de verschillende microservices, en de verbanden daartussen. Ook vergt ontwikkeling van nieuwe features die over meerdere microservices spannen extra management om te zorgen dat het als een geheel kan werken.

Wat maakt grid computing dan interessant als platform?

Grid computing is sterk in populariteit gestegen sinds Google het MapReduce principe heeft gepubliceerd in 2004 (zie MapReduce: Simplified Data Processing on Large Clusters door Jeffrey Dean en Sanjay Ghemawat). Tegenwoordig zijn er verschillende open source, en commerciële pakketten beschikbaar die het makkelijk maken een computing grid of cluster te maken en beheren. Alhoewel MapReduce deze trend ingeluid heeft is het een methodiek om complexe berekeningen te parallelliseren. MapReduce is dan ook niet een methodiek die geschikt is voor het ondersteunen van een microservices architectuur.

Wat wel interessant is, is dat veel software pakketten die grid computing verzorgen mogelijkheden bieden om services in het grid computing cluster te hosten. Daardoor wordt het grid computing cluster eigenlijk de infrastructuur voor de microservices:

Grid computing cluster als microservices infrastructuur
Figuur 2: Een cluster met daarin een aantal servers die verschillende services beschikbaar stellen

Buiten dat de platforms de infrastructuur bieden om de microservices aan te bieden zijn er nog een aantal voordelen die de huidige pakketten bieden. Interessant is bijvoorbeeld het automatisch delen van informatie tussen nodes zodat elke microservice altijd up-to-date is. Dit maakt het veel eenvoudiger om microservices parallelliseerbaar te maken.

Een nadeel is dat er nog niet echt standaarden zijn voor grid computing platforms. Dat betekent dat er al snel een afhankelijkheid van één specifiek platform ontstaat. Dit is een wezenlijk verschil met bijvoorbeeld webapplicaties die (mits volgens de standaarden gebouwd) gebruik kunnen maken van verschillende soorten applicatie servers.

Beschikbare grid computing software

Microservices architectuur is niet een architectuur waar veel frameworks voor te vinden zijn, maar er zijn wel een aantal grid computing frameworks die services ondersteunen. Hieronder een kleine selectie van grid computing software.

Het eerste voorbeeld is Hadoop. Hadoop is een framework voor het gedistribueerd verwerken van data. Alhoewel sommige microservices wel dergelijke functionaliteit zullen hebben is Hadoop meer geschikt voor parallelliseerbare complexe berekeningen. Hadoop wordt veel gebruikt als framework voor de MapReduce methodiek.

Een ander voorbeeld is Hazelcast. Hazelcast is een uitgebreid framework dat verschillende soorten activiteiten op een cluster ondersteunt. Mogelijkheden zijn data caching, MapReduce-achtige berekeningen, en services. Hazelcast is dan ook geschikt als framework om een microservices architectuur in een grid te faciliteren. Hazelcast biedt verschillende varianten van open source tot enterprise pakketten met commerciële support.

Als laatste Ignite. Ignite is net als Hazelcast een uitgebreid framework. Verschillende soorten activiteiten worden ondersteund zoals data caching, computation door middel van MapReduce etc. Het maken van een service in een grid lijkt in Ignite iets eenvoudiger te zijn, maar de verschillen zijn niet heel groot. Er is een commerciële variant van Ignite genaamd GridGain.

In de rest van dit Whitebook wordt gebruik gemaakt van Ignite.

Hoe werkt een ignite cluster

Een ignite cluster bestaat uit een of meer nodes. Er kan onderscheid gemaakt worden tussen client nodes (die niet actief meedoen in het verwerken van aanvragen), en server nodes (die wel meedoen in het uitvoeren van aanvragen). Elke node heeft wat configuratie die de node vertelt hoe deze opgestart moet worden, bij welk cluster deze hoort, waar naar andere nodes gezocht moet worden, en welke services gestart moeten worden. De configuratie kan zowel in code gedaan worden, of door middel van een XML bestand.

Voorbeeld van een Ignite cluster zoals weergegeven door Ignite zelf
Figuur 3: Voorbeeld van een Ignite cluster zoals weergegeven door Ignite zelf

Bij het opstarten gaat een node op zoek (discovery) naar andere nodes in hetzelfde cluster, standaard door een multicast, maar in de meeste gevallen is het wenselijk om de discovery expliciet te configureren. Zodra een andere node gevonden wordt, wordt de nieuw opgestarte node opgenomen in het cluster en kan deze gebruikt worden. Bij het afsluiten of crashen van een node zal deze ook automatisch uit het cluster verwijderd worden.

Hoe worden services gebruikt in Ignite

Het is vrij eenvoudig om een service in Ignite te maken. Eerst moet er een interface gemaakt worden die de service beschrijft:

package nl.whitehorses.gridcompute.domain;
import java.util.List;
public interface GridService {
    List<String> geefData(String basis);
}

Dan moet er een implementatie van de service gemaakt worden die in het cluster gaat draaien. Deze moet zowel de gedefinieerde interface implementeren als de service interface die Ignite specificeert:"

package nl.whitehorses.gridcompute.server;

import nl.whitehorses.gridcompute.domain.GridService;
import org.apache.ignite.services.Service;
import org.apache.ignite.services.ServiceContext;

import java.util.Arrays;
import java.util.List;

public class GridServiceImpl implements GridService, Service {


    public void cancel(ServiceContext serviceContext) {
        // niet gebruikt
    }

    public void init(ServiceContext serviceContext) throws Exception {
        // niet gebruikt
    }

    public void execute(ServiceContext serviceContext) throws Exception {
        // niet gebruikt
    }

    public List geefData(String basis) {
        return Arrays.asList(basis.split(" "));

    }
}

Deze service is nog vrij simpel, de tekst die er ingaat wordt opgesplitst in losse woorden, en teruggegeven. Het is zelfs niet nodig om de methodes van de Ignite Service interface te implementeren. Het bovenstaande is alles dat nodig is om een service in een Ignite grid te laten werken. Er is echter nog wel wat configuratie nodig om het geheel op te starten. In dit geval is er gekozen om de XML configuratie optie te gebruiken. Deze configuratie ziet er dan als volgt uit:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
	    <!-- Distributed Service configuration. -->
		<property name="serviceConfiguration">
			<list>
				<bean class="org.apache.ignite.services.ServiceConfiguration">
					<property name="name" value="GridService"/>
					<property name="maxPerNodeCount" value="1"/>
					<property name="totalCount" value="1"/>
					<property name="service">
					  <ref bean="gridServiceImpl"/>
					</property>
				</bean>
			</list>
		</property>
	</bean>
	
	<bean id="gridServiceImpl" class="nl.whitehorses.gridcompute.server.GridServiceImpl" />
</beans>

Deze configuratie zorgt er voor dat er in het cluster een service gemaakt wordt genaamd “GridService”. Per node in het cluster mag er maximaal 1 instantie van de service actief zijn, en er moet in totaal 1 instantie zijn van de service. Effectief zal deze service dus maar 1 maal in het grid voorkomen. Als laatste wordt er geconfigureerd welke klasse de service aanbiedt. Dit is dus de implementatie die eerder getoond werd.
De laatste stap is dan het aanroepen van zo’n service door een client. Daarvoor moet eerst een verbinding naar het cluster gemaakt worden (als die er nog niet is), de service opgezocht worden, en dan uiteindelijk aangeroepen worden.

package nl.whitehorses.gridcompute.client;

import nl.whitehorses.gridcompute.domain.GridService;
import org.apache.ignite.Ignite;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.IgniteConfiguration;

import java.util.List;

public class GridServiceConsumer {

    public List geefData(String basis) {
        IgniteConfiguration igniteConfiguration = new IgniteConfiguration();
        igniteConfiguration.setClientMode(true);
        Ignite ignite = Ignition.start(igniteConfiguration);

        GridService service = ignite.services().serviceProxy("GridService", GridService.class, /*sticky*/ false );

        return service.geefData(basis);
    }
}

Deze client kent dus alleen maar de “GridService” interface. De implementatie draait op een van de servers in het cluster. De client hoeft alleen de interface te kennen van de server. Het cluster zorgt er voor dat de aanroep correct bij een van de draaiende implementaties komt.

De client kent alleen de interface; het cluster zorgt voor de rest
Afbeelding 4: De client kent alleen de interface; het cluster zorgt voor de rest

Uitdagingen bij het gebruik van clusters

Het is met Ignite niet moeilijk om een (micro)service in een cluster te draaien. Echter heeft een dergelijke architectuur wel zijn uitdagingen. Om te beginnen is cluster software weer een extra discipline die beheerst moet worden door de organisatie. Van ontwikkelaars tot beheer, er moet voldoende kennis opgebouwd worden.

Verder zijn de cluster software pakketten over het algemeen zelf organiserend. Dat is ook een groot voordeel, maar het betekent ook dat er maar beperkt invloed uitgeoefend kan worden op hoe de services over het cluster verdeeld worden. In ieder geval Hazelcast adviseert daarom om bij microservices een cluster per microservice te maken.

Als laatste zit er wel een vendor lock-in aan vast. Er zijn (in ieder geval binnen java) nog geen standaarden voor cluster software. Ook zullen de services binnen een cluster aan een programmeertaal vast zitten. De meeste grid computing oplossingen bieden wel clients in verschillende programmeertalen aan, maar de services in het cluster moeten wel van dezelfde taal gebruikmaken als het grid computing pakket.

Conclusie

Zowel Microservices als Grid Computing zijn concepten waar in Nederland nog niet veel mee gedaan wordt bij grotere bedrijven. Dat is ook logisch want het gaat hier om een compleet nieuwe architectuur. En dan wel een architectuur die het fundament raakt van hoe applicaties ontworpen en gebouwd worden. Toch zijn er veel partijen die toch deze architectuur omarmen zelfs bij bestaande applicatie-landschappen.

De voordelen van een Microservices architectuur zijn dan ook groot. Door een groot complex geheel in vele kleine componenten te splitsen blijft ieder individuele component overzichtelijk, en is het realistisch om het geheel te overzien. Het opdelen van een applicatie in modules is al heel gebruikelijk, Microservices architectuur maakt dat alleen maar een stuk explicieter.

Grid Computing clusters zijn dan weer een goede onderlaag voor de Microservices architectuur. De inherente complexiteit in de infrastructuur die bij Microservices architectuur hoort wordt goed ondersteund door de cluster technologie.

Beide technologieën hebben echter wel hun nadelen. Microservices architectuur is niet een architectuur die bij elke applicatie en/of bedrijf zal passen. Net als Service Oriented Architecture moet de hele IT-infrastructuur er op ingericht zijn. Grid computing cluster pakketten beperken de IT-infrastructuur dan nog een stuk meer. Beide zijn concepten waar kennis in opgebouwd zal moeten worden om het effectief in te kunnen zetten, en om te weten wanneer het niet ingezet kan of moet worden.

Toch zijn beide technieken te interessant om niet te overwegen. De potentiele voordelen zijn groot. Een goed opgezet applicatielandschap van Microservices ondersteund door een Grid Computing pakket levert een geheel op dat dynamisch, effectief en vooral heel schaalbaar is.

Waardering:
 
Tags:

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.