Follow Us on Twitter

Data-grids met Coherence

November 2008 - Bij gedistribueerde en geclusterde applicaties wordt traditioneel uitgegaan van een database mechanisme om gezamenlijke data tussen de verschillende onderdelen te delen. Wanneer data alleen gedeeld moet worden binnen nodes en niet weggeschreven hoeft te worden op disk, is een database een relatief zware oplossing. Het kost vaak relatief veel moeite om data heen en weer te sturen terwijl er eigenlijk geen persistentie nodig is, of deze persistentie mag best achterlopen op de applicatie.

Een andere mogelijkheid is om gebruik te maken van berichten, bijvoorbeeld met behulp van JMS. Dit heeft echter als nadeel dat de data steeds op maar een enkel punt in de groep applicaties is, en dat het niet eenvoudig is om een specifiek stuk data op te roepen.

Een relatief nieuwe techniek die veel van de voorgenoemde problemen oplost is grid computing, en dan specifiek data-grids. Deze data-grids slaan objecten op in het geheugen en hebben deze dan snel paraat als de applicatie deze nodig heeft. Coherence [1] is Oracle's variant van een data-grid. In dit Whitebook wordt toegelicht wat Coherence is en waarvoor en hoe je Coherence kunt gebruiken.

Wat is Coherence?

Grid computing is het gebruik van meerdere servers om een enkele taak te doen. Er zijn vele manieren om gebruik te maken van grid computing, een voorbeeld is de MapReduce technologie [2] van Google, welke onder andere gebruikt wordt om statistieken als zeitgeist [3] te genereren.

Coherence is een data grid. In het geval van data grids is de taak van de grid het beheren van data. Kort samengevat is de data grid verantwoordelijk voor het managen en delen van (grote) hoeveelheden gedistribueerde data. Het grote voordeel van data grids is dat deze grote hoeveelheden data betrouwbaar, fout-tolerant en met een goede performance kunnen beheren.

Coherence verzorgt echter niet persistentie zoals een database dat doet. In veel situaties is het niet nodig dat de data permanent wordt opgeslagen en daar is Coherence voor bedoeld. Het feit dat er meerdere nodes zijn zorgt al voor een goede betrouwbaarheid aangezien de data beschikbaar is op meerdere nodes. Als er een node uitvalt dan verzorgen andere nodes dat de data van deze node alsnog beschikbaar is voor de applicatie.

Een voorbeeld is de situatie van een winkelmandje bij een webshop. Wanneer één node uitvalt moet het winkelmandje bewaard blijven, zodat de bezoeker van de webshop de inhoud niet kwijt raakt. Niet noodzakelijk is dat de data wordt weggeschreven naar de database: dat is pas nodig wanneer de bezoeker haar bestelling afrondt.

Hieronder wordt de werking van Coherence schematisch weergegeven [1]. Er zijn 4 nodes, die ieder een eigen JVM gebruiken. Binnen alle nodes is Coherence actief als Replicated Cache Map.

Vanuit JVM 1 wordt element A in de cache gezet door de applicatie die in dezelfde JVM draait. Coherence zorgt ervoor dat een kopie van A in alle nodes beschikbaar wordt. Hetzelfde geldt voor element D die door de applicatie op JVM 2 geplaatst wordt.

Vervolgens wordt element A gelezen van zowel JVM 1 en 3. De cache van Coherence bevat dezelfde elementen in alle nodes. Geen netwerkcommunicatie is nodig tussen de verschillende nodes: zowel JVM 1 en 3 als JVM 2 en 4 hoeven niet een en dezelfde (database)server aan te roepen.

Coherence is wel eventueel in staat om voor persistentie naar een database, ofwel wegschrijven naar disk, te zorgen. Alleen als data niet gegarandeerd aan het einde van een transactie weggeschreven moet worden, kan Coherence persistentie versnellen. Later in het artikel wordt hier verder op in gegaan.

Waarvoor kan Coherence gebruikt worden

Coherence is vooral geschikt voor situaties waarbij dezelfde informatie gedeeld wordt met meerdere applicaties en waarbij er een goede performance vereist is. De applicaties kunnen meerdere instanties van hetzelfde programma zijn, bijvoorbeeld ten behoeve van load balancing. Maar ook totaal verschillende applicaties die elkaars data gebruiken, bijvoorbeeld een frontend en een backend applicatie.

Ook als er gebruik gemaakt wordt van een database waarbij een beperkte set data uit de database erg vaak wordt gebruikt kan er voor gekozen worden om deze data in Coherence te zetten en zo de database te ontlasten en de performance te verbeteren.

Het voorbeeld wat we in de rest van dit Whitebook ter illustratie zullen gebruiken is een webshop applicatie waarbij er load balancing gebruikt wordt. Coherence wordt dan gebruikt om een registratie van de winkelmanden van gebruikers bij te houden.

Gebruiksvormen

Er zijn een aantal vormen waarin Coherence gebruikt kan worden. De meest makkelijke methode is als een complete in-memory “database”. Hierbij word alle data in het geheugen opgeslagen. Als alle servers uitvallen is deze data ook verloren. Een winkelmand van iemand die nog aan het rondkijken is zou dan verdwijnen. In veel situaties is dit echter geen probleem, als alle servers uitgaan is de applicatie toch onbereikbaar en waarschijnlijk voor langere tijd. Sommige situaties vereisen echter dat de data voor langere tijd met zekerheid bewaard word, daar is de tweede vorm voor bedoeld.

De tweede vorm is een combinatie met een database. Als er data opgevraagd wordt uit Coherence, dan wordt deze ook in de database opgezocht. Als objecten in de data-grid gezet worden, dan worden ze (eventueel met een vertraging) gepersisteerd naar de database. Dit biedt een mooie combinatie van de performance van Coherence en de betrouwbaarheid van een database. Het vergt meer ontwikkelwerk en configuratie dan de eerste vorm, maar biedt ook meer zekerheid.

Uiteraard zijn er ook een aantal tussen-oplossingen: de data in Coherence kan opgeslagen worden in bestanden waardoor deze niet verloren gaat bij een shutdown van alle servers. Als de hard disk van een server faalt, dan heeft tenminste één andere server nog een kopie van de data. Om een situatie op te vangen wanneer de disk van meerdere servers kapot gaat, is deze oplossing niet geschikt.

Als laatste is er nog de mogelijkheid om Coherence als cache manager te gebruiken bij een persistency framework als JPA, Hibernate, of Toplink. In dit geval is het gebruik van Coherence transparant voor de gebruiker. Hierdoor wordt dus persistentie gerealiseerd in combinatie met de performance voordelen van Coherence.

Voorbeeld

Als voorbeeld geven we hier een webshop applicatie, Coherence word gebruikt om een winkelmandje bij te houden. Om wat meer van de mogelijkheden van Coherence te laten zien wordt er niet per gebruiker één enkel winkelmandje bijgehouden, maar worden alle losse items in het winkelmandje in de data-grid gezet. Met behulp van filters wordt dan gekeken welke items door de gebruiker in het winkelmandje gezet zijn.

Het object dat in het winkelmandje zit (Artikel) heeft de volgende attributen met de bijbehorende getters en setters:

gebruikersnaam: naam van de gebruiker die dit item geselecteerd heeft 
naam: het geselecteerde artikel 

Elke keer dat de gebruiker een artikel toevoegt aan het winkelmandje wordt er een instantie van Artikel gemaakt en in Coherence gezet. Om alle geselecteerde artikelen te tonen worden deze met behulp van een filter uitgelezen.

Aanspreken Coherence

Het aanspreken van coherence is vrij eenvoudig: één enkele call naar een factory klasse levert een NamedCache object op welke voor alle handelingen met Coherence gebruikt wordt. De cache wordt geïdentificeerd door een naam, waardoor een enkel Coherence data-grid meerdere caches kan hebben. Bijvoorbeeld een voor de winkelmanden en een voor de ingelogde gebruikers. Elk van deze named caches kan gezien worden als een soort tabel.

NamedCache winkelmanden = CacheFactory.getCache(“winkelmanden”); 

Deze code zorgt ervoor dat het volgende gebeurt:

  1. De statische getCache methode van de CacheFactory klasse controleert of er al een Coherence node in de JVM draait
    • Indien er nog geen node draait wordt deze opgestart.
    • Met behulp van multicast word gezocht naar andere nodes en wordt er een verbinding met deze nodes opgezet indien zij bestaan.
  2. Er word een NamedCache object gemaakt welke verwijst naar de node die in de JVM draait, en welke naar het “winkelmanden” deel van de data grid kijkt. Dit object wordt dan gebruikt voor verdere acties.

Toevoegen artikel

Om een artikel toe te voegen wordt deze simpelweg in de cache gezet. Er moet een key en een value gebruikt worden, voor het gemak gebruiken we het artikel ook als key:

Artikel artikel = new Artikel(); 
artikel.setGebruikersnaam(“Piet”); 
artikel.setNaam(“Coherence”); 
winkelmanden.put(artikel, artikel); 

Dit stuk code gebruikt de NamedCache instantie die eerder gemaakt was en voegt daar een entry aan toe. De cache is gemodelleerd als een set van key en value paren.

Uitlezen met behulp van een Filter

Nu het artikel in de cache staat kan de cache uitgelezen worden. In dit geval gebruiken we een filter. Ter illustratie worden zowel de keys als de values die passen bij de filter uitgelezen in respectievelijk het keys, en het values object:

Filter filter = new EqualsFilter(“getGebruikersnaam”, “Piet”); 
Set keys = winkelmanden.keySet(filter); 
Set values = winkelmanden.entrySet(Filter); 

De filter die hierboven gedefinieerd wordt bepaald dat alleen die objecten teruggegeven worden waarvan het resultaat van de getGebruikersnaam methode “Piet” is. Wederom wordt er van dezelfde NamedCache instantie gebruik gemaakt.

Beperkingen

Er zitten wel beperkingen aan het gebruik van Coherence. Het is duidelijk de bedoeling dat de servers waar een Coherence data grid op draait relatief dicht bij elkaar staan en in hetzelfde ip subnet geplaatst worden. Dit is ook nodig om een goede performance te waarborgen aangezien grotere afstanden ook voor langere toegangstijden zorgen.

Een belangrijk aspect van Coherence is dat het uitvallen van een node transparant opgevangen wordt door de andere (nog werkende) nodes. Het is dan echter wel nodig om de nodes op verschillende fysieke servers te plaatsen. Fail-over tussen verschillende virtual machines op dezelfde server heeft geen nut als de server onderuit gaat.

De filters waarmee gezocht kan worden naar objecten in de data-grid gaan er vanuit dat de methodes die in de filter gespecificeerd worden ook daadwerkelijk bestaan. Stel dat er twee typen data-objecten gebruikt worden waarbij het ene type een methode getNaam() heeft en de ander niet. Een filter welke eist dat getNaam() “Coherence” teruggeeft zal niet werken, zelfs al geeft een van de data-objecten deze waarde terug. Het is daarom aan te bevelen om voor elk type object een aparte cache te gebruiken.

Een ander punt van aandacht is dat de objecten die uit de data-grid komen, losstaan van het bron-object in de data-grid. Dit betekent dat als er aanpassingen gedaan worden aan het object die ook in de data-grid terecht moeten komen dat het object expliciet weer terug in de data-grid gezet moet worden.

Aan het begin is al benoemd dat een data grid geen persistentie laag is. Coherence kan wel gebruikt worden in combinatie met persistentie frameworks als JPA, Hibernate en Toplink, maar biedt zelf maar beperkte persistentie mogelijkheden. Daarom is in situaties waar persistentie nodig is Coherence geschikt als een side cache waarbij aanpassingen aan objecten die gepersisteerd moeten worden zowel naar de data grid als naar de database geschreven worden. In het geval van de webshop zal de winkelwagen dus alleen in de data grid staan. Zodra een bestelling geplaatst wordt, zal deze bestelling naar de database verstuurd moeten worden.

Samenvatting

Coherence is een makkelijk te gebruiken systeem om gedistribueerd data te bewaren in het geheugen. Hierdoor is het een stuk eenvoudiger om applicaties schaalbaar te houden doordat een nieuwe server toevoegen niet veel meer inhoudt dan de applicatie op deze nieuwe server te starten, zolang de andere servers bereikbaar zijn in hetzelfde subnet.

Referenties

 

  1. www.oracle.com/technology/products/coherence
  2. labs.google.com/papers/mapreduce-osdi04.pdf
  3. www.google.com/intl/en/press/zeitgeist
  4. wiki.tangosol.com/display/COH33UG/Replicated+Cache+Service

 

Waardering:
 

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.