Geavanceerde NoSQL persistentie met RavenDB

 
05 november 2013

RavenDB is een document database gebouwd in .Net en ook primair gericht op het .Net platform. Het valt onder de NoSQL categorie en is qua opzet enigszins vergelijkbaar met CouchDB. In RavenDB werk je niet met tabellen en relaties maar met documenten (een JSON representatie van een object of objectboom).

In de basis kun je met RavenDB eenvoudig een simpele persistentie in je applicatie bouwen. Het is simpel te installeren en je kan met minimale code al objecten opslaan en queries uitvoeren. Maar er zitten ook zeer geavanceerde features in. Het is vanaf het begin opgezet om schaalbaar te zijn en kan eenvoudig omgaan met verschillende replicatie scenario’s en sharding. En omdat het uitvoeren van queries gebaseerd is op Lucene zijn dingen als een full-tekst-search eenvoudig te implementeren. Daarnaast zijn er veel nuttige extra functionaliteiten beschikbaar.

Voor veel applicaties is RavenDB hiermee een valide alternatief voor een SQL Server persistentie met bijvoorbeeld NHibernate, Entity Framework of rauwe SQL.

Hoe werkt RavenDB intern

Intern bestaat RavenDB in hoofdlijnen uit drie onderdelen. De document store waar je data in zit, de Lucene indexen waarop je kunt queriën en de index definities die de Lucene indexen genereren.

  1. 1. De document store
    De document store is het onderdeel waar je data is opgeslagen. Hier worden je objecten opgeslagen als geserialiseerde JSON documenten en je kunt hier eenvoudige CRUD bewerkingen op uitvoeren. De document store is volledig ACID en transactioneel.
  2. 2. De Lucene indexen
    De document store ondersteund enkel eenvoudige CRUD bewerkingen en dat is voor de meeste applicaties niet voldoende. Je moet queries kunnen uitvoeren op je data. Omdat RavenDB geen relationele database is kun je niets met SQL en in plaats daarvan wordt er gebruik gemaakt van Lucene indexen. De documenten in de store worden geïndexeerd met Lucene en op deze indexen kun je queries uitvoeren. Hierbij kun je volledig gebruik maken van de zoekfaciliteiten die Lucene biedt. En nog een voordeel: queriën op Lucene indexen is zeer snel.
  3. 3. Map/reduce index definities
    Welke indexen er zijn wordt bepaald door de index definities. De index definities omschrijven welke data op welke manier geïndexeerd moet worden. Dit wordt gedaan met behulp van map/reduce functies.

image

Een belangrijk aspect van hoe RavenDB intern werkt is dat de Lucene indexen op de achtergrond worden bijgewerkt als er iets wijzigt in de document store. Door deze opzet wordt het het meeste werk verricht na het wijzigen van een document als de indexen worden bijgewerkt en is het doen van een query een hele lichte taak (want een query op een Lucene index kost weinig). Dit is precies omgekeerd met de werking van een standaard relationele database waarbij het wijzigen van een rij een goedkope operatie is en queries de meeste kracht kosten. Bij de meeste applicaties worden er meer lees- dan schrijfbewerkingen gedaan en past het model dat RavenDB aanhoudt beter.

Consequentie van het op de achtergrond bijwerken van de indexen is wel dat de informatie in de indexen enigszins achterloopt op de state van de document store. Het kan dus voorkomen dat je resultaten terug krijgt die niet geheel actueel zijn. In praktijk blijkt dit meestal geen problemen op te leveren en als je echt wil kun je het systeem dwingen om gegarandeerd actuele gegevens te leveren. Hierbij verlies je echter wel een stuk van de performance en schaalbaarheid.

Connectie maken met de database

Er zijn verschillende manieren waarop je RavenDB kunt aanspreken. De server is geheel toegankelijk via een REST laag waarmee alle functionaliteit is aan te roepen over HTTP. Je werkt dan met de JSON representatie van de objecten die je opgeslagen hebt. Naast de REST interface is er ook een .Net cliënt Hiermee wordt het werken met RavenDB een stuk eenvoudiger. De conversie tussen JSON en je objecten gebeurt transparant, er is changetracking op je objecten zodat je eenvoudig wijzigingen kunt opslaan, het ‘unit of work’ pattern zit ingebakken en je kunt eenvoudig meedraaien in .Net transacties. Het werken met RavenDB is hiermee enigszins vergelijkbaar met NHibernate, maar dan wat eenvoudiger en zonder de mappings.

Naast alle manieren om technisch te koppelen met RavenDB is er (uiteraard) ook een management interface. Als je vanuit de browser connectie maakt krijg je een silverlight applicatie waarmee je databases kunt beheren.

Hoe werk je in de praktijk met RavenDB

Installatie

Starten met RavenDB is niet moeilijk. Je kunt de server downloaden op http://ravendb.net/download en deze starten door /Server/Raven.Server.exe uit te voeren waarna RavenDB beschikbaar is op http://localhost:8080. In het project waar je gebruik wil maken van RavenDB installeer je vervolgens het NuGet package “RavenDB.Client” zodat je de .Net cliënt kunt gebruiken.

Eenvoudig data opslaan

Er zijn twee classes in RavenDB belangrijk om connectie te maken met de server. De DocumentStore waarvan in principe één instantie actief is in je applicatie. Deze is onder andere verantwoordelijk voor de configuratie van de connectie en het aanmaken van een DocumentSession. De DocumentSession gebruik je voor het opslaan en ophalen van je data en bevat qua levensduur één unit-of-work.

Als we een simpel model nemen van een persoon die een adres heeft dan is dit de volledige code om connectie met de database te maken en een nieuw persoon op te slaan:

createobject

En dat is het. Geen mapping files of complexe configuratie. Veel simpeler kan niet.

Een query doen

Zoals al vermeld worden queries uitgevoerd op Lucene indexen die opgebouwd worden met map/reduce. Eén van de handige features van RavenDB is dat hij de index definities ook zelf kan aanmaken op basis van de query die je uitvoert. In de praktijk kun je dus volgende standaard LINQ query uitvoeren waarna RavenDB zelf de benodigde index definitie aanmaakt, de index creëert en het resultaat van de query terug geeft. Vaak is dit voldoende en hoef je alleen bij geavanceerdere queries zelf de index te maken.

savepersoon

De kracht van RavenDB

RavenDB bezit een hele reeks aan sterke punten. Het is eenvoudig om mee te werken, er is een actieve community en het wordt zeer actief doorontwikkeld. Het model waarbij leesbewerkingen goedkoop zijn en je schrijfbewerkingen wat duurder is vaak ideaal en doordat het gebruik maakt van Lucene zijn echte ‘search engine’ functionaliteiten zoals full-text search, facets, highlighting en recommendations relatief eenvoudig toe te voegen aan je applicatie. En er zijn nog veel meer features die je kunnen helpen. Kijk bijvoorbeeld naar de extra plugins die je kunt activeren http://ravendb.net/docs/server/extending/bundles .

Er is wel sprake van een leercurve. Het is echt iets anders dan een relationele database. Met een document database moet je op een andere manier nadenken over hoe je je data opslaat. Meer in aggregates en minder in de derde normaalvorm (http://bit.ly/17CSNxb). Verder is het werken met map/reduce en Lucene wennen als je dat nog nooit hebt toegepast. Je hoeft gelukkig niet alles zelf uit te vinden want we hebben binnen Sogyo al de nodige ervaring opgedaan. Daarnaast is er documentatie (http://ravendb.net/docs) en er is een Google Group waar ervaren en behulpzame gebruikers je kunnen helpen (http://bit.ly/1b2MDD9).

Conclusie

In een paar jaar is RavenDB een serieus alternatief geworden voor de relationele database. Het is ondertussen de default storage engine geworden voor NServiceBus en we hebben het zelf al succesvol bij een aantal projecten voor klanten ingezet. Tijd dat jij ook om gaat! Wil je eenvoudig experimenteren, lees dan ook mijn vorige artikel over AppHarbor (http://bit.ly/17JzY9s) want die bieden RavenDB ook als service aan.

[[ In de interne nieuwsbrief van Sogyo schrijf ik, onder de titel ‘gave technologie’, over technologiën waar ik enthousiast over ben en waarvan ik vind dat iedere collega op zijn minst moet weten dat het bestaat.
Dit artikel komt uit de Sogyo Nieuwsbrief van november 2013 ]]


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


Categorieën: Development, .Net, databases

Tags: , ,


Reactie

  • Don H schreef:

    Na lang zoeken en veel proberen heb ik uiteindelijk mijn antwoord inzake het starten met RavenDB hier kunnen vinden. Op de site van RavenDB zelf wordt het niet 1-2-3 duidelijk.. hier wel! Top dus! Bedankt!

    Geplaatst op 23 april 2014 om 16:19 Permalink