Schaalbaarheid: event-driven praktijk

 
25 april 2010

Tijdens het (overigens zeer geslaagde) Café over schaalbaarheid afgelopen donderdag was er wat discussie over een event-gedreven implementatie door een aantal Sogyo’ers de afgelopen maanden ontworpen, gemaakt en inmiddels in productie gebracht.

eventdriven

Bovenstaande afbeelding geeft inzicht in de structuur van de applicatie. Vanuit een hardware-aansturing worden events opgevangen en via een centrale dispatcher-component gedistribueerd naar aangesloten componenten (in dit geval: nul of meer clients, een “domain model” component, een datawarehouse component (DWH) en de hardware zelf). De applicatie kan tot een paar honderd events per seconde te verwerken krijgen. De keuze is om via een centrale dispatcher component (geïmplementeerd in een paar regels code) alle events die binnenkomen uit de verschillende componenten tevens weer naar alle componenten te verspreiden. Er vindt dus in de dispatcher geen filtering plaats.

Dit was volgens een aantal mensen geen schaalbare oplossing. Ik wil dat bij deze weerleggen: ik denk namelijk dat deze oplossing tot honderden (in theorie duizenden) aangesloten clients zal schalen. Het bewijs in de vorm van een test ga ik nog leveren, hier allereerst de onderbouwing op papier (volgens Dijkstra overigens de enige juiste manier ;)).

De events worden asynchroon verstuurd. De dispatcher heeft dus per event dat afgevuurt wordt slechts één statement uit te voeren per aangesloten listener (DWH, hardware of client). Zoals wel bekend is het uitvoeren van één statement niet iets dat bijzonder lang hoeft te duren (een processor lopend op 2 GHz zou dat in principe in een halve nanoseconde moeten kunnen doen). Laten we er echter van de andere kant af rekenen. Ik had het over 200 events per seconde. Dat betekent dat elk event binnen 5 milliseconden afgehandeld moet worden. In het ideale geval zou de simpele dispatcher dan dus (5 milliseconden / 0.5 nanoseconde) = 10 miljoen (!) subscribers kunnen bedienen. Laten we uitgaan van een minder ideale situatie: een factor 1000 overhead voor communicatie bijvoorbeeld. Dan hebben we het nog altijd over 10.000 subscribers die bediend kunnen worden in deze tijdspanne.

Voor diegene die het dan nog niet zien, laten we een paar mogelijke eenvoudige uitbreidingen aangeven op de dispatcher. Ten eerste, voor drukke momenten wel handig: een queue. Dit maakt dat we de dispatcher ongeacht van de inkomende stroom continue op volle toeren kunnen laten draaien. Een andere interessante: parallel verwerken van events. Ik gaf al aan dat de notificaties asynchroon verstuurd worden. Echter, je kunt nog een niveau van asynchroniteit introduceren: voor elk event een aparte thread opstarten die de distributie regelt. Dit maakt eventuele delays in communicatie bij notificaties ook irrelevant.

Kortom: lineaire schaalbaarheid is iets krachtigs, zie ook:  http://en.wikipedia.org/wiki/Linear_time#Linear_time. Als we dus de simpele regel van “uitbreiding is optellen” (en niet: uitbreiden is vermenigvuldigen of kwadrateren) hanteren dan komt alles wel (of het nou half zes is of niet ;)).


Werken met ?
Kijk dan bij onze mogelijkheden voor zowel starters als ervaren engineers.


Categorieën: Development


Reactie

  • Timon schreef:

    Met betrekking tot de schaalbaarheid van een event driven architecture. Alle oplossingen die voor het schalen van netwerken worden gebruikt, kunnen worden toegepast op een event driven architecture. Een actor kan je zien als computer (/ netwerk-node) en een event(/ message) als een… tja een message. Het internet kan je dus volgens mij zien al bewijs dat een event driven architecture schaalt.

    Wanneer de dispatcher de bottleneck of een gevaar voor de robuustheid is, dan zou je kunnen overwegen om een peer-to-peer-event-driven-architecture te maken. Waarbij alle actoren ook een kleine rol als dispatcher krijgt. Het is maar een idee.

    Verder kan ik bevestigen dat het Sogyo Cafe over schaalbaarheid een groot succes was.

    Geplaatst op 26 april 2010 om 14:45 Permalink