La cache che vive nella memoria
Quasi un quinto delle immagini di contatore che questo servizio disegna non cambia più nulla. Uno script di tracciamento del mouse della generazione precedente ricarica l'immagine a ogni movimento, e da quando quelle richieste non incrementano più niente, due di fila producono la stessa immagine, byte per byte.
Un candidato ovvio per una cache. Le decisioni interessanti erano dove metterla e su cosa far vertere la chiave.
Non sul disco
Questo gira su un Raspberry Pi, e il disco è una scheda SD. Metterci in cache le immagini disegnate avrebbe significato circa 70 MB di scrittura al giorno, in cambio di un risparmio misurato di 1,6 minuti di CPU al giorno.
È un cattivo scambio. Le schede SD muoiono di scrittura, e ciò che si compra è un errore di arrotondamento su una macchina che non è limitata dalla CPU. La cache vive perciò in /dev/shm, cioè tmpfs, cioè RAM. Misurato lì: 0,027 ms per leggere, 0,036 ms per scrivere, 1,9 GB liberi.
Tutto sparisce al riavvio. Per una cache non è una perdita, è il caso normale.
Sullo stesso Pi gira Redis. Non è stato usato, per un motivo che con la tecnica non c'entra: appartiene a un'altra applicazione ed è protetto da password per essa. Condividere un'istanza legherebbe due servizi senza rapporto, così che una brutta giornata dell'uno diventi una brutta giornata dell'altro.
La chiave contiene i numeri
La chiave di cache abituale è un'identità più una scadenza, e la scadenza è una scommessa: negli ultimi cinque minuti non è cambiato nulla di importante. In un contatore, ciò che cambia è esattamente ciò che viene mostrato.
I valori mostrati finiscono quindi dentro la chiave. Se un numero cambia, è un'altra chiave, e l'immagine viene ridisegnata. La scommessa sparisce invece di essere fatta con cura. Ogni visita contata incrementa almeno il totale di sempre, quindi nessuna visita contata può ricevere un'immagine scaduta. La scadenza che resta è solo un limite superiore per i valori che non stanno nella chiave — le cifre settimanali, mensili e annuali.
Cosa andava verificato prima
Una cache è sicura solo se ciò che conserva è funzione della sua chiave. Questa è un'affermazione su ogni singolo design, ed è stata verificata invece che presunta:
- nessun design usa
rand(),mt_rand(),shuffle()ouniqid() - nessun design legge l'orologio più finemente che a ore
- i parametri di tracciamento del vecchio script non vengono letti da nessuna parte nell'albero
Quest'ultimo punto ha prodotto il più bel fallimento dell'intero esercizio. Finché quei parametri facevano parte della chiave, ogni richiesta portava coordinate del mouse leggermente diverse, quindi ogni chiave era irripetibile. La cache ha funzionato per un giorno intero e ha registrato 13 successi. Funzionava perfettamente e non faceva nulla, che è il tipo di guasto più difficile da notare.
E se qui qualcosa fallisce — cartella illeggibile, disco pieno, voce corrotta — l'immagine viene disegnata nel modo normale. Una cache non deve mai essere il motivo per cui un contatore non compare.