TPP2 - De caches uitgelegd

Door AtleX op vrijdag 4 september 2009 09:38 - Reacties (4)
Categorieën: Development & code, Tools, Views: 5.372

In deze post stipte ik al heel kort de diskcache van TPP2 aan. In deze blogpost leg ik uit wat de diskcache is, de geschiedenis ervan binnen TPP2 en hoe deze werkt.

Als eerste, wat is het in godsnaam? Nou, da's heel simpel. De diskcache is een kopie van het fotoalbum zoals dat bij T.net op de servers staat. Zowel thumbnails als volledige afbeeldingen worden opgeslagen op de harde schijf van de gebruiker. En waarom? Simpelweg, om de snelheid.

De eerste prototype builds van TPP2 bevatten geen diskcache. Zodra er een map werd geopend werden alle thumbnails in die map gedownload en getoond. Bij het bekijken van een andere map verdwenen deze thumbnails weer, omdat ze alleen maar in het geheugen bewaard werden. Hetzelfde gebeurde met een full-size afbeelding, deze werd gedownload zodra hij bekeken werd en daarna weer verwijderd. Het werkt, maar het zorgt op z'n zachtst gezegd voor nogal rammelende gebruikers-ervaring. Bij een wat langzamere verbinding kon het openen van een map zo een paar minuten duren en het tonen van een volledige afbeelding was een paar seconden per afbeelding ook niet echt snel te noemen. Het was meer vergelijkbaar met een YouTube-filmpje bekijken via een antiek 56K6-modem.

Al snel had ik daarom een primitieve diskcache ingebouwd. Gedownloade afbeeldingen werden daarbij opgeslagen op de harde schijf van de gebruiker. Dat was al een hele verbetering omdat het nu alleen nog maar traag was zodra een map of afbeelding voor de eerste keer geopend werd.

Maar helaas, het systeem kende meer na- dan voordelen. Zodra een map geopend werd moest ik alsnog een lijst met afbeeldingen opvragen om te bepalen of er nieuwe afbeeldingen waren toegevoegd en deze eventueel downloaden. Dat beetje netwerkverkeer was voldoende om TPP2 alsnog niet 'snappy' aan te laten voelen. Conclusie: De simpele aanpak was niet voldoende.

Daarom ben ik begonnen met iets wat ik voor het gemak maar DiskCache v1 noem. Zodra TPP is gestart werd het volledige fotoalbum, thumbnails en full-size afbeeldingen, gedownload naar de hard disk. Dat werkte als volgt:
  • Maak de exacte kopie van de directory-structuur van het fotoalbum aan op de harde schijf (de diskcache)
  • Bouw een lijst met alle afbeeldingen in het fotoalbum
  • Verwijder alle afbeeldingen die wel bestaan op de harde schijf maar niet in de lijst
  • Maak een lijst van afbeeldingen die wel bestaan in het fotoalbum, maar niet op de harde schijf.
  • Download alle afbeeldingen die nog niet bestaan naar de diskcache op de harde schijf
Je programmeert wat classes, gooit dat in de ketel, voegt een snufje threading toe aangelengd met wat events en in combinatie met een leuke formuliertje om de voortgang te tonen heb je een werkende diskcache.

Totdat je wat verder gaat denken en gaat testen. Het eerste probleem: afbeeldingen kunnen vervangen worden in het fotoalbum, een afbeelding wordt daarbij vervangen door een andere waarbij de ID (de naam, voor het gemak) hetzelfde blijft. Heel handig als je bijvoorbeeld de verkeerde afbeelding upload, maar niet handig als je aan de hand van die ID's de lijst met te downloaden afbeeldingen bouwt.

Gelukkig was dit eenvoudig op te lossen. Niet alleen nieuwe afbeeldingen moeten gedownload worden, maar ook afbeeldingen die in het fotoalbum een recentere datum/tijd hebben dan de versie in de diskcache.

Dan het tweede probleem. Ik deed een hoop met moeite om de directory-structuur van het fotoalbum op te bouwen in de diskcache om vervolgens in de juiste map de gedownloade afbeeldingen op te slaan. Het fotoalbum heeft alleen een keigave feature waarmee je afbeeldingen kan verplaatsen van de ene map naar de andere. De ID's blijven dan ook weer gelijk. Bij de DiskCache v1 werden dan eerst de afbeeldingen verwijderd uit de oude directory om vervolgens naar hun nieuwe bestemming gedownload te worden.

Dat moest anders, want naast nutteloos bandbreedte gebruiken zorgde het er ook voor dat het synchroniseren trager was. Daarom bedacht ik een keigaaf systeem waarmee voor elke afbeelding in het fotoalbum werd gekeken of hij al op disk stond en of hij in de juiste directory stond. Zo niet, dan werd hij verplaatst. Leuk, gaaf, geweldig! Totdat ik na een week eens wat performance tests ging doen en mijn disk I/O sky-high zag gaan bij een synchroniseer-actie. Oeps...

Een uurtje navelstaren later kwam ik op het idee om de hele directory-structuur in de diskcache overboord te gooien. Elke afbeelding heeft een uniek ID en kan dus prima in dezelfde folder staan. FAT32 wordt amper nog gebruikt en NTFS heeft toch geen zinnige limiet op files per directory dus dat was geen enkel probleem. Dus heb ik de hele directory-structuur uit het systeem gegooid en nu bestaat de diskcache uit twee mappen; één met de volledige afbeeldingen en één met thumbnails. Voilà, DiskCache v2!



Dat was een systeem wat een week of twee is meegegaan, totdat ik vond dat de boel toch nog niet snel genoeg was. Bij het openen van een map met veel afbeeldingen had ik veel disk I/O wat de boel traag maakte en het tonen van full-size afbeeldingen duurde ook te lang.

Daarom heb ik bovenop de diskcache een tweede cache gemaakt: De memory cache. Hiervan zijn er twee, elk met een instelbare capaciteit. De eerste is voor thumbnails en heeft een standaard capaciteit van 1000 thumbnails en de tweede, waarin 15 afbeeldingen passen, is voor volledige afbeeldingen.

Zodra er een map geopend wordt worden alle thumbnails in die map in de thumbnail cache geladen. Als de gebruiker de map dan nogmaals openklikt worden de thumbnails dan uit de memory cache geladen, in plaats van vanaf de harde schijf. Dat levert een leuke performancewinst op, mijn foto's van AutoRAI 2007 doet er de eerste keer iets meer dan een seconde over om te laden op mijn PC en daarna, als de afbeeldingen uit de memory cache komen, nog maar zo'n 500ms.

De 2e cache dient ervoor om volledige afbeeldingen op te kunnen slaan. Deze is een stuk kleiner, met een capaciteit van 15 afbeeldingen. In TPP2 zit vanzelfsprekend namelijk ook de mogelijkheid om full-size afbeeldingen te bekijken:
http://tweakers.net/ext/f/jcKdaMrbjNFRKjVdIuzrIDiC/thumb.jpg
Dit venster heeft zoals je misschien al gezien hebt 2 pijltjes waarmee de vorige en de volgende getoond kan worden. Dat werkt best snel, zeker als een afbeelding al in de cache aanwezig is. Alleen bij grote afbeeldingen kon het opvragen van de volgende afbeelding nogal traag zijn, al gauw zo'n 500-1000ms. Daarom wordt er zodra er een volledige afbeelding bekeken wordt ook alvast de volgende in de cache geladen. Dat zorgt ervoor dat gebruikers veel sneller door kunnen klikken.

Dit alles kost wel wat natuurlijk, namelijk relatief veel geheugen. Ik had eerst de cache voor volledige afbeeldingen 50 afbeeldingen groot gemaakt, maar toen ik daarmee meer dan 800MB geheugen ging gebruiken kwam ik daar snel op terug. Na flink wat tunen en meten ben ik uiteindelijk op 15 afbeeldingen uitgekomen. Dat zorgt voor een snellere gebruikservaring zonder excessief veel geheugen te gebruiken.

Een tweede beperker van het geheugengebruik is iets wat al vanaf het begin in het memory caching systeem zit. Namelijk: de schoonmaakster. Deze draait op een instelbare interval en ruimt alle afbeeldingen op die sinds de laatste opruimactie niet meer bekeken zijn.

Dit doet ze niet altijd, er is namelijk ook nog een instelbare loadfactor. De thumbnail cache moet bijvoorbeeld voor 80% of meer vol zitten voordat deze opgeruimd wordt. Hiermee voorkom ik dat ik nutteloze CPU cycles verspil aan opruimacties terwijl zeker de thumbnail cache niet veel geheugen gebruikt.

De housekeeper heeft een leuke effect op het geheugengebruik. In de volgende afbeelding zijn de caches behoorlijk gevuld:
http://tweakers.net/ext/f/D4dTfYMabmJWrBYzRVIFrbkl/thumb.png
Hierbij is meteen te zien dat de grootte van de caches in te stellen zijn, voor deze test was hij beperkt tot 750 voor de thumbnail cache. :)

Na een paar minuten komt de schoonmaakster langs en daalt het geheugengebruik weer aanzienlijk:
http://tweakers.net/ext/f/z6onR0HUQCurqKav59kUvdgT/thumb.png

Mensen met weinig geheugen kunnen natuurlijk de grootte van de caches beperken. De grootte van de thumbnail cache loopt van 100 tot 2000 en de van de volledige afbeeldingen kun je elke waarde kiezen tussen de 5 en 50. De hoogste waarde kan ik hierbij niet aanraden, 1500MB geheugengebruik is hiermee prima mogelijk. :X :P

Volgende: TPP2 - De versie voor thumbdrives 08-'09 TPP2 - De versie voor thumbdrives

Reacties


Door Tweakers user Fiander, vrijdag 4 september 2009 09:49

Maar helaas, het systeem kende meer voor dan nadelen.
Helaas meer voor dan na delen ?

Verder zou je nog in je database bij kunnen houden welke foto's echt daadwerkeijk bekeken worden. het kost je inderdaad een round trip, maar je zou daarna de meest bekeken foto's eerder kunnen uploaden dan de bijna nooit bekeken.
je zou per dag het aantal daadwerkelijke views kunnen bij houden, en dan uploaden in volgorde van de meeste views per vorige 30 dagen. zo krijgen nieuwe fotos ook een kans om sneller hoger op de lijst te komen.

natuurlijk wel gewoon alle thumbs uploaden.

Door Tweakers user AtleX, vrijdag 4 september 2009 09:55

Helaas meer voor dan na delen ?
Oeps... Fixed. :)
Verder zou je nog in je database bij kunnen houden welke foto's echt daadwerkeijk bekeken worden.het kost je inderdaad een round trip, maar je zou daarna de meest bekeken foto's eerder kunnen uploaden dan de bijna nooit bekeken.
je zou per dag het aantal daadwerkelijke views kunnen bij houden, en dan uploaden in volgorde van de meeste views per vorige 30 dagen. zo krijgen nieuwe fotos ook een kans om sneller hoger op de lijst te komen.

natuurlijk wel gewoon alle thumbs uploaden.
Sorry, maar dit volg ik niet helemaal? Ik cache het complete fotoalbum op disk, en afbeeldingen uit die diskcache die de gebruiker van TPP2 bekijkt in het programma worden ook nog in-memory gecached. Waarom zou ik dan extra roundtrips naar T.net moeten doen en waarom moet ik het aantal views per dag bijhouden?

[Reactie gewijzigd op vrijdag 4 september 2009 09:55]


Door Tweakers user Fiander, vrijdag 4 september 2009 10:02

Wat ik bedoelde,
stel 1000 afbeeldingen.
jij houd per afbeelding bij hoevaak deze echt bekeken word.
sommige worden vaak bekeken, andere zijn niet interesant.
de eerste krijgen veel views, de laatste weinig views.

als iemand dan connectie maakt welke nog niks in cache heeft, kun je dan
afbeeldingen in volgorde van waarschijnlijkheid dat ie bekeken word in de cache zetten.
dus de afbeeldingen met veel views eerst.

Als je de views per dag bij houd, kun je een lopende piek gebruiken.
als 1 foto op dag 1 100 keer bekeken word, en daarna niet meer, zal ie na 30 dagen weer op 0 staan. andere fotos welke elke dag 3 of 4 keer bekeken worden, zullen langzaam oplopen tot een piek op 30 dagen.

Door Tweakers user AtleX, vrijdag 4 september 2009 10:07

Ja, maar hoe vaak een afbeelding uit een fotoalbum bekeken wordt is toch totaal niet interessant voor de caching binnen TPP2? De eigenaar van het fotoalbum gebruikt TPP2 om deze te managen, voor de cache binnen TPP2 is het dus alleen maar interessant wat de gebruiker van TPP2 bekijkt.

In mijn eigen fotoalbum zijn afbeeldingen soms 10000x bekeken, maar binnen TPP2 heb ik ze nog nooit geopend. Moet ik ze dan cachen? Ik denk het niet, schijnbaar zijn die afbeeldingen voor mij niet interessant meer. :)

[Reactie gewijzigd op vrijdag 4 september 2009 10:08]


Reageren is niet meer mogelijk