La caché que vive en la memoria
Cerca de una quinta parte de las imágenes de contador que dibuja este servicio ya no cambian nada. Un script de seguimiento del ratón de la generación anterior recarga la imagen con cada movimiento, y desde que esas peticiones dejaron de incrementar nada, dos seguidas producen la misma imagen, byte a byte.
Un candidato evidente para una caché. Lo interesante fueron las decisiones sobre dónde ponerla y sobre qué debía basarse la clave.
En el disco no
Esto corre en una Raspberry Pi, y el disco es una tarjeta SD. Cachear ahí las imágenes dibujadas habría supuesto unos 70 MB de escritura al día, a cambio de un ahorro medido de 1,6 minutos de CPU al día.
Es un mal intercambio. Las tarjetas SD mueren de escribir, y lo que se compra es un error de redondeo en una máquina que no está limitada por CPU. Así que la caché vive en /dev/shm, que es tmpfs, que es RAM. Medido allí: 0,027 ms para leer, 0,036 ms para escribir, 1,9 GB libres.
Todo desaparece al reiniciar. Para una caché eso no es una pérdida, es el caso normal.
En la misma Pi corre Redis. No se usó, por un motivo que nada tiene que ver con la técnica: pertenece a otra aplicación y está protegido con contraseña para ella. Compartir una instancia ataría dos servicios sin relación, de modo que un mal día de uno se convertiría en un mal día del otro.
La clave contiene los números
La clave de caché habitual es una identidad más una caducidad, y la caducidad es una apuesta: en los últimos cinco minutos no ha cambiado nada importante. En un contador, lo que cambia es exactamente lo que se muestra.
Así que los valores mostrados van dentro de la clave. Si un número cambia, es otra clave, y la imagen se dibuja de nuevo. La apuesta desaparece en lugar de hacerse con cuidado. Cada visita contada incrementa al menos el total histórico, así que ninguna visita contada puede recibir una imagen caducada. La caducidad que queda es solo un límite superior para los valores que no están en la clave — las cifras semanales, mensuales y anuales.
Lo que hubo que comprobar antes
Una caché solo es segura si lo que guarda es función de su clave. Eso es una afirmación sobre cada diseño, y se comprobó en vez de darse por supuesta:
- ningún diseño usa
rand(),mt_rand(),shuffle()niuniqid() - ningún diseño lee el reloj con más finura que por horas
- los parámetros de seguimiento del script antiguo no se leen en ninguna parte del árbol
Ese último punto produjo el mejor fracaso de todo el ejercicio. Mientras esos parámetros formaban parte de la clave, cada petición traía coordenadas del ratón ligeramente distintas, así que cada clave era única. La caché estuvo un día entero funcionando y registró 13 aciertos. Funcionaba perfectamente sin hacer nada, que es la clase de avería más difícil de notar.
Y si aquí falla algo — directorio ilegible, disco lleno, entrada corrupta — la imagen se dibuja de la forma normal. Una caché nunca debe ser la razón de que un contador no aparezca.