Sunday, January 1, 2012

Varnish, Etags, och Cache Invalidation

Försöker hitta en optimal lösning för Varnish med hjälp av Etags. I princip tror jag att jag är ute efter att flera Etags kan vara giltiga samtidigt för en viss resurs.

Scenariot
- Tre olika klienter med tom cache gör varsin request, klient #2 är inloggad, #1 och #3 är inte inloggade.
- Varnish cache är tom innan första requesten görs
- Alla klienter hämtar samma sida, låt säga "/forum", inga edge side includes eller liknande.
- Back-end returnerar endast Etag och eventuellt 304-svar om klienten inte är inloggad. Annars returneras ett helt vanligt svar med privata cache-headers etc.

Om requesterna görs i ordningen 1-2-3
#1: Får fräsch sida, sparas i Varnish cache
#2: Får fräsch sida, Varnish cache rensas för objektet
#3: Får fräsch sida, sparas i Varnish cache

Om de görs i ordningen 1-3-2
#1: Får fräsch sida, sparas i Varnish cache
#3: Får cachad sida
#2: Får fräsch sida, Varnish cache rensas för objektet

Möjlig lösning
Konfigurera Varnish så att den inte gör något alls (specifikt; så den inte invaliderar cachen) om ingen Etag kommer från backend, utan bara skickar vidare requesten till klienten. Går säkert att konfa så, verkar ganska flexibelt.

Nästa problem: Flera valida Etags
Om vi har flera varianter av en sida, för olika typer av oinloggade besökare. Exempelvis vill vi cacha sidan olika för om webbläsaren stödjer lazyload av våra annonser eller inte. Då har vi plötsligt två eller fler konkurrerande Etags för samma resurs, som kommer invalidera varandra.

Detta borde dock Varnish kunna hantera; den skulle ju kunna skicka flera Etags med en "If-None-Match"-header till backend. Frågan är hur den ska veta vilken som ska invalideras när den får tillbaka en 200 istället för 304?

No comments: