Een miljoen beelden
7 September 2009 15:37 · Peter Brouwer · Ruby
De nationalebeeldbank verkoopt foto’s. Vooral allerdaags Nederlands beeld. Zo heeft het beelden in voorraad van de windmolen in Aagtekerke tot de ophaalbrug in Zwinderen. Fotografen kunnen er hun beelden uploaden en klanten kunnen deze vervolgens kopen. Recentelijk heb ik daar 3 maanden mogen werken om hun bestaande website te voorzien van een nieuwe look, het implementeren van nieuwe zoekalgoritmes, het migreren naar de (oh zo mooie buzzwoord) Cloud, het implementeren van back office systemen en het draaiende houden van een site met een miljoen beelden. In dit blogartikel wil ik graag wat technische aspecten van dit traject belichten.
De omgeving
Als we The waybackmachine mogen geloven bestaat de beeldbank sinds juli 2006. De site is gebouwd met behulp van Ruby on Rails. Dit framework werd in juli 2004 openbaar gemaakt en bestond dus pas twee jaar. De site zal toen gebouwd zijn met behulp van rails versie 1.1.x. Ondertussen is rails versie 2.3.4 net uitgekomen en is het een en ander behoorlijk veranderd wat gezien wordt als “good practices” in een rails applicatie. Het upgraden van een zo “oude” applicatie naar de nieuwste versie is een hele klus op zich. Een punt waar we even bij stil hebben gestaan aan het begin van het traject was of we de hele applicatie opnieuw zouden bouwen, of door zouden gaan met wat er al stond. Als dit soort discussies ontstaan moet ik altijd denken aan de mooie serie blogartikelen van Chad Fowler, “The Big Rewrite”, waarin hij beschrijft waarom het herimplementeren van een bestaand software product vaak geen succes wordt, zijn belangrijkste punten:
- Het is makkelijk om te zeggen “De nieuwe applicatie moet hetzelfde doen als de oude”, terwijl niemand eigenlijk weet wat de oude applicatie precies doet. “I unscientifically conclude that almost all production software is in such bad shape that it would be nearly useless as a guide to re-implementing itself”
- Nieuwe feature wensen verstoren het proces dermate dat ze uiteindelijk meer tijd in beslag nemen dan het herschrijven van de oude applicatie.
- Het is onvermijdelijk dat er fixes op het oude systeem uitgevoerd moeten worden terwijl je bezig bent met het nieuwe systeem.
- Data migratie van het oude systeem naar het nieuwe systeem is lastig.
- De vraag “Waarom herschrijven we het systeem?” is lastig te beantwoorden. Hoe meer schaalbaar wordt het? Wat heb ik er aan dat de code mooier wordt? Hoeveel sneller kan je nieuwe features toevoegen in het nieuwe systeem?
Hoewel iets opnieuw maken, zonder alle “rommel” van je voorgangers, natuurlijk erg leuk lijkt, ben ik blij dat we besloten hebben om met het oude systeem verder te gaan. Veel delen zijn wel flink herschreven en de applicatie is nog niet helemaal RESTfull, maar er staat toch een goed werkende applicatie, waar prima mee verder te werken is.
Plaatjes schalen
De nationalebeeldbank.nl draait natuurlijk om foto’s. Het lastige van foto’s is dat ze groot zijn. En dat je er ook nog eens een miljoen van hebt, waar er elke dag honderden bijkomen, maakt dingen niet makkelijker. Na het uploaden van een foto door een fotograaf wordt deze geschaald naar een 3-tal andere formaten. Dit proces kost veel resources. Als er dan ook nog memory leaks blijken te zitten in de gebruikte image library, RMagick, is het niet gek dat de site soms wel heel erg traag wordt. Het vervangen van RMagick met MiniMagick maakte het proces al een stuk sneller en betrouwbaarder. Een citaat uit de README van MiniMagick:
I was using RMagick and loving it, but it was eating up huge amounts of memory. A simple script like this…
<em>Magick::read("image.jpg") do |f| f.write("manipulated.jpg") end </em>
…would use over 100 Megs of Ram. On my local machine this wasn’t a problem, but on my hosting server the ruby apps would crash because of their 100 Meg memory limit.
EC2 en S3
De nationalebeeldbank.nl trekt veel bezoekers en veel fotografen zijn constant bezig met het uploaden van nieuwe beelden. Het geheugen en harde schijf gebruik is erg hoog. Dit, in combinatie met de ambitie om in andere landen live te gaan met de site heeft ons doen besluiten om de site te migreren naar EC2 en S3. EC2 moet zorgen voor het makkelijk horizontaal kunnen schalen van de applicatie. In principe is het een druk op de knop om een nieuwe server er bij te zetten om de load te verdelen tussen meerdere servers (instances in EC2 termen). S3 zorgt voor oneindig veel opslagplek, zodat je je geen zorgen hoeft te maken of je nog wel genoeg opslagruimte hebt voor alle foto’s. Je slaat je data op in zogenaamde buckets, die je kan zien als directories. Buckets kunnen of opgeslagen worden in Amerika of in Europa. De gem die we gebruiken voor het opslaan van gegevens op S3 is de aws-s3 gem. Het enige nadeel van deze gem is dat hij er van uit gaat dat je je data in Amerika wilt opslaan. Wat aanpassingen aan de gem waren dus noodzakelijk om de data te kunnen opslaan in Europa. Je wilt niet dat alle plaatjes bereikbaar zijn voor alle mensen, je moet ze immers eerst kopen voordat je ze kan downloaden. S3 maakt dit mogelijk met een uitgebreid rechtensysteem. Je kan aan zowel buckets als individuele files permissies toekennen en geauthoriseerde url’s genereren die toegang geven tot beschermde plaatjes. Schijfruimte op S3 is helaas niet goedkoop. 18 cent per maand per GB loopt toch snel op als je een paar TB aan plaatjes hebt. De overgang van een filesysteem naar S3 brengt wel veel veranderingen met zich mee aan een systeem, files worden anders benaderd en opgeslagen. Ik verwacht dat Libraries als cloudloop (http://www.cloudloop.com/) die het transparant maken hoe data opgeslagen wordt steeds meer ingezet zullen worden. Er zijn dan geen code veranderingen nodig om te switchen tussen het gebruik maken van een traditioneel filesysteem of een opslagplek als S3.
Al met al een mooie klus, waar ik met plezier gewerkt heb en een hoop geleerd over html/javascript, ruby, rails, ec2/s3 en plaatjes.













Gaaf dat jullie met EC2 en S3 aan de slag gegaan zijn! Waar hebben jullie de database gelaten? Op EBS?
Overigens een leuke gem voor het verwerken van afbeeldingen is Paperclip van Thoughtbot (http://www.thoughtbot.com/projects/paperclip). Deze gem maakt direct van ImageMagick gebruik, zonder tussenkomst van MiniMagick of RMagick.
Stefan Borsje - September 7, 2009 21:42
Ja! De database staat op EBS. (Persistente data kan je niet bewaren op ec2 instances, je verliest al je data als je een instance opnieuw opstart.)
Paperclip is een goeie tip, dacht dat hij achter de schermen ook RMagick gebruikte. Je kan ook direct in paperclip aangeven dat je je plaatjes op s3 wil opslaan, ideaal dus. Al zal het script dat het overzetten van alle bestaande plaatjes naar een directory/bucket structuur die paperclip snapt wel een paar nachten draaien.
Peter Brouwer - September 7, 2009 22:37
Leuk verhaal! gebruik zelf eigenlijk alleen nog maar paperclip, RMagick is daar niet voor nodig, wel ImagMagick.
jeroen - September 14, 2009 10:00