Cachning av räknarbilder i minnet
Nära en femtedel av räknarbilderna som tjänsten ritar ändrar inte längre någonting. Ett skript från den förra generationen som följer muspekaren laddar om bilden vid varje rörelse, och eftersom de förfrågningarna slutade räkna upp något ger två av dem i rad samma bild, byte för byte.
En självklar kandidat för en cache. De intressanta besluten var var den skulle ligga och vad nyckeln skulle bygga på.
Inte på disken
Det här körs på en liten server, och disken är ett SD-kort. Att cacha ritade bilder där hade inneburit ungefär 70 MB skrivningar per dag, i utbyte mot en uppmätt besparing på 1,6 minuter CPU-tid per dag.
Det är en dålig affär. SD-kort går sönder av skrivningar, och det man köper är ett avrundningsfel på en maskin som inte begränsas av CPU:n. Därför ligger cachen i /dev/shm, som är tmpfs, alltså RAM. Uppmätt där: 0,027 ms för läsning, 0,036 ms för skrivning, 1,9 GB ledigt.
Allt försvinner vid omstart. För en cache är det ingen förlust, det är normalfallet.
Redis körs på samma maskin. Den användes inte, av ett skäl som inte har med teknik att göra: den tillhör ett annat program och är lösenordsskyddad för det. Att dela en instans skulle binda ihop två orelaterade tjänster, så att en dålig dag för den ena blir en dålig dag för den andra.
Nyckeln innehåller siffrorna
Den vanliga cachenyckeln är en identitet plus en utgångstid, och utgångstiden är ett vad: inget viktigt har ändrats de senaste fem minuterna. För en räknare är det som ändras precis det som visas.
Därför hamnar de visade värdena i nyckeln. Om en siffra ändras är det en annan nyckel, och bilden ritas på nytt. Vadet försvinner i stället för att göras försiktigt. Varje räknat besök räknar upp åtminstone totalsumman, så inget räknat besök kan få en inaktuell bild. Den utgångstid som finns kvar är bara en övre gräns för de värden som inte finns i nyckeln — vecko-, månads- och årssiffror.
Vad som måste kontrolleras först
En cache är bara säker om det den cachar är en funktion av nyckeln. Det är ett påstående om varje design, och det kontrollerades i stället för att antas:
- ingen design använder
rand(),mt_rand(),shuffle()elleruniqid() - ingen design läser klockan noggrannare än per timme
- spårningsparametrarna från det gamla skriptet läses ingenstans i källträdet
Den sista gav hela övningens bästa misslyckande. Medan de parametrarna fortfarande ingick i nyckeln hade varje begäran lite olika muskoordinater, så varje nyckel var unik. Cachen körde en hel dag och registrerade 13 träffar. Den fungerade perfekt och gjorde ingenting, vilket är den svåraste sortens fel att upptäcka.
Och om något här fallerar — oläsbar katalog, full disk, skadad post — ritas bilden helt enkelt på vanligt sätt. En cache får aldrig vara anledningen till att en räknare inte visas.