Stapje voor stapje data migreren

Als er één constante is in softwareontwikkelland, dan is het wel dat software constant verandert. Nieuwe inzichten noodzaken ontwikkelaars om hun code aan te passen om bepaalde use cases (beter) te kunnen ondersteunen. Soms betekent dat dat bepaalde algoritmen moeten worden vervangen, andere keren betekent dat dat er een aanpassing moet plaatsvinden in het model waar de algoritmen gebruik van maken.

Modelwijzigingen

Die laatste situatie kan problemen opleveren. De meeste applicaties maken gebruik van data die is opgeslagen in een database. Hoe ga je bij modelwijzigingen om met data die is opgeslagen volgens een inmiddels verouderd model?

Er zijn twee opties: ofwel je beschouwt alle oude data als verloren, ofwel je vindt een manier om de verouderde data om te zetten naar het nieuwe model. De eerste optie is in de meeste gevallen onaanvaardbaar. Uitzonderingen zijn: privéprojecten of applicaties die zich nog in een pilotfase bevinden.

In alle andere gevallen zal er een datamigratie plaats moeten vinden. Ook hier bestaan twee smaken in: ofwel je migreert alle data in één keer - de zogenaamde big bang -, ofwel je doet dat stapje voor stapje.

Big bang

Mijn team heeft jarenlang van dat eerste smaakje mogen proeven in onze legacy-applicatie. We hadden een aparte tool ontwikkeld die gebruik maakte van de applicatiecode om de database te benaderen. In die tool gaven we aan welke eigenschappen sinds de modelwijziging waren veranderd. Vervolgens drukten we op een knop, en - tada! - de data was weer up to date.

Deze oplossingsrichting is relatief eenvoudig, maar niet zonder nadelen. Ten eerste speelt er een coördinatievraagstuk. Wanneer je de nieuwe code uitrolt zonder het migratiescript op de productieomgeving te draaien, wordt de applicatie onbruikbaar. Andersom geldt dat, als je geen boze gebruikers wil, je het migratiescript niet kunt draaien zonder de nieuwe code uit te rollen.

Dit maakt een uitrol een heikel punt, dat goede afstemming vergt met gebruikers. Je kunt niet elke nieuwe wijziging zomaar meer doorzetten naar je productieomgeving. Als gevolg daarvan hopen codewijzigingen zich op. Wanneer er dan een bug wordt ontdekt, valt moeilijk na te gaan bij welke wijziging deze erin is geslopen.

Een tweede probleem is schaalbaarheid. In de loop der jaren was de database van onze applicatie enorm gegroeid. Hierdoor was de migratie geen kwestie van seconden meer, zoals op onze ontwikkellaptops, maar minuten. Als er halverwege de migratie een probleem ontstond, dan was onze data in corrupte staat geraakt en moest de boel terug worden gedraaid. Vervolgens begon het proces weer van voren af aan.

Dit is het soort ervaringen waar horrorverhalen uit worden geboren.

Proof of concept

Met deze ervaringen in het achterhoofd, besloot het team te onderzoeken of het tweede smaakje misschien niet een aantrekkelijker optie was.

Twee factoren speelden daarbij in ons voordeel. (1) Onze nieuwe applicatie maakt gebruik van RavenDB, een NoSQL-database die objecten opslaat in JSON-formaat. (2) Er bestaat open source tooling in de vorm van Migrations.Json.Net, die één of meerdere migratiescripts uit kan voeren bij het serialiseren of deserialiseren van JSON naar objecten.

Tijdens de proof of concept (POC) waarin we deze technieken met elkaar combineerden, deden we de volgende inzichten op:

Stapje voor stapje

Door verouderde data stapje voor stapje te migreren naar een nieuw model, worden de nadelen van onze oorspronkelijke oplossingsrichting verholpen. De modelwijziging en migratiecode worden tegelijkertijd uitgerold en vergen vervolgens geen handmatige actie meer van het ontwikkelteam. Het coördinatieprobleem is dus van de baan.

Hetzelfde geldt voor de schaalbaarheidsproblematiek. Het kritieke moment waarop alle data moest worden gemigreerd, is uitgesmeerd over een veelvoud aan niet-kritieke momenten. In tegenstelling tot de bulkmigratie, kan de migratie van individuele objecten snel en pijnloos gebeuren.

Bovendien is de oplossing eenvoudig te bouwen door gebruik te maken van onze bestaande tooling in combinatie met open source-software.

Kleven er dan helemaal geen nadelen aan deze oplossingsrichting? Ongetwijfeld wel. Maar daar zullen we in de loop van de tijd pas achter komen, stapje voor stapje. En dan zal ik vast en zeker een blog schrijven over de zegeningen van big bang-datamigraties.

databases · datamigratie · leermoment · nosql · open source · procesverbetering · proof of concept · software ontwikkelen · testen