Cache în memorie pentru imaginile contoarelor
Aproape o cincime din imaginile de contor pe care le desenează acest serviciu nu mai schimbă nimic. Un script de urmărire a mouse-ului din generația anterioară reîncarcă imaginea la fiecare mișcare și, de când acele cereri nu mai incrementează nimic, două dintre ele la rând produc aceeași imagine, octet cu octet.
Un candidat evident pentru un cache. Deciziile interesante au fost unde să fie pus și pe ce să se bazeze cheia.
Nu pe disc
Totul rulează pe un server mic, iar discul este un card SD. Stocarea în cache a imaginilor desenate pe el ar fi însemnat aproximativ 70 MB de scrieri pe zi, în schimbul unei economii măsurate de 1,6 minute de timp CPU pe zi.
Este un schimb prost. Cardurile SD se defectează din cauza scrierilor, iar ce se câștigă este o eroare de rotunjire pe o mașină care nu este limitată de CPU. Așa că cache-ul se află în /dev/shm, care este tmpfs, adică RAM. Măsurat acolo: 0,027 ms la citire, 0,036 ms la scriere, 1,9 GB liberi.
Totul dispare la repornire. Pentru un cache, asta nu este o pierdere, ci situația normală.
Pe aceeași mașină rulează Redis. Nu a fost folosit, dintr-un motiv care nu are nimic de-a face cu tehnologia: aparține altei aplicații și este protejat cu parolă pentru ea. Partajarea unei singure instanțe ar lega între ele două servicii fără legătură, astfel încât o zi proastă pentru unul ar deveni o zi proastă și pentru celălalt.
Cheia conține cifrele
Cheia de cache obișnuită este o identitate plus o expirare, iar expirarea este un pariu: nimic important nu s-a schimbat în ultimele cinci minute. La un contor, lucrul care se schimbă este exact lucrul afișat.
Așa că valorile afișate intră în cheie. Dacă se schimbă un număr, este o altă cheie, iar imaginea este desenată din nou. Pariul dispare, în loc să fie făcut cu grijă. Fiecare vizită numărată incrementează cel puțin totalul general, deci nicio vizită numărată nu poate primi o imagine învechită. Expirarea care rămâne este doar o limită superioară pentru valorile care nu sunt în cheie — cifrele săptămânale, lunare și anuale.
Ce a trebuit verificat mai întâi
Un cache este sigur doar dacă ceea ce stochează este o funcție de cheia sa. Aceasta este o afirmație despre fiecare design și a fost verificată, nu presupusă:
- niciun design nu folosește
rand(),mt_rand(),shuffle()sauuniqid() - niciun design nu citește ceasul mai fin decât la nivel de oră
- parametrii de urmărire din scriptul vechi nu sunt citiți nicăieri în arborele de cod
Ultima a produs cel mai bun eșec al întregului exercițiu. Cât timp acei parametri făceau încă parte din cheie, fiecare cerere avea coordonate de mouse ușor diferite, deci fiecare cheie era unică. Cache-ul a funcționat o zi întreagă și a înregistrat 13 potriviri. Funcționa perfect și nu făcea nimic, ceea ce este tipul de defecțiune cel mai greu de observat.
Iar dacă ceva eșuează aici — director ilizibil, disc plin, intrare coruptă — imaginea este pur și simplu desenată în mod normal. Un cache nu trebuie să fie niciodată motivul pentru care un contor nu apare.