Tasa de aciertos de caché y calidad de la política de caché
La tasa de aciertos es sólo un indicador de resultados. Lo que realmente determina el coste del sistema es el modo de fallo, la presión de retorno y el radio de propagación del error.
Cuando muchos equipos hablan de almacenamiento en caché, lo primero que dicen es la tasa de aciertos.
Una tasa de acierto del 95% suena bien; El 98% parece estar optimizado; El 99% incluso da a la gente la ilusión de que el sistema ha sido “domesticado”.
Pero cuando algo sale mal en línea, todo el mundo suele ver otro conjunto de problemas al revisar: la base de datos es penetrada después de que un determinado lote de claves caduque al mismo tiempo, los usuarios siguen viendo datos antiguos una hora después de que se cambia el precio, el nodo de caché tiembla y las consultas más caras llegan directamente a la base de datos principal.
Mi juicio es simple: ** El objetivo de la estrategia de caché es controlar el costo de los “errores”. ** Una tasa de aciertos alta sólo significa que se leen muchas solicitudes en la memoria caché; no significa que el diseño de la falla sea correcto, no significa que el costo de regresar a la fuente sea controlable y no significa que los errores se limitarán a un rango pequeño.
Si un caché aumenta la tasa de aciertos del 92 % al 99 %, pero a costa de hacer que sea más difícil de invalidar, más difícil de localizar datos sucios y más probable que se forme una tormenta de regreso al origen durante la fluctuación, entonces lo más probable es que no se trate de una optimización, sino que simplemente traslada la complejidad de la base de datos a otro rincón.
La pregunta no es “cuántos aciertos”, sino “dónde acertar cuando fallas”
El indicador de tasa de aciertos tiene un defecto natural: aplana la distribución de frío y calor.
Una interfaz recibe un millón de solicitudes al día, 990.000 de las cuales leen detalles de productos populares y las 10.000 restantes leen productos de cola larga. Guarde en caché los datos populares y la tasa de aciertos será muy buena de inmediato. Pero si esos 10.000 fallos de cola larga recaen en la consulta más lenta y costosa que también implica unir tablas, la presión de la base de datos puede no ser menor de lo imaginado.
En otras palabras, la tasa de aciertos se cuenta como “número de veces”, pero el costo del sistema a menudo se liquida como “precio”. **
Esto también muestra que algunos equipos están viendo claramente hermosos indicadores de caché, pero la CPU de la base de datos aún no puede disminuir la velocidad: el caché bloquea solicitudes baratas y los fallos realmente costosos todavía se ejecutan al descubierto.
Al juzgar una estrategia de almacenamiento en caché, prefiero mirar primero tres cosas:
- Omitir la parte más cara de la solicitud;
- Si los errores se producirán de forma concentrada y no uniforme;
- ¿Se transmitirá el estrés aguas abajo después del fallo?
Estas tres preguntas están más cerca del costo real que “¿la tasa general de aciertos aumentó otros 2 puntos?”
Lo que realmente determina la calidad del caché suele ser el método de falla.
Muchos accidentes de caché se deben esencialmente a que “el diseño de fallas es demasiado aproximado”.
El enfoque más común es simplemente establecer un TTL. La implementación es simple y los indicadores son fáciles de mejorar, porque siempre que el TTL sea lo suficientemente largo, la tasa de aciertos no suele ser tan mala. Pero hay dos problemas típicos con los esquemas TTL.
En primer lugar, deja tiempo para decidir cuándo caducan los datos, en lugar de cambios comerciales. **
Los precios han cambiado, el inventario ha cambiado, los permisos han cambiado, pero el caché sigue vivo. Por supuesto, el TTL se puede acortar, pero una vez que se acorta el TTL, la frecuencia de retorno a la fuente aumentará nuevamente. Muchos equipos van y vienen entre “los datos antiguos son demasiado antiguos” y “la base de datos está demasiado ocupada”.
En segundo lugar, es fácil crear errores de sincronización. **
Si un lote de teclas de acceso rápido se escribe al mismo tiempo y usa el mismo TTL, lo más probable es que caduquen juntas en un momento similar. Normalmente, la tasa de aciertos está bien, pero tan pronto como alcance el punto de vencimiento, habrá un pico instantáneo de regreso a la fuente. Puede que esto sólo sea una inquietud de cinco minutos en el tablero, pero es un golpe muy real para la base de datos y los servicios posteriores.
Por lo tanto, lo más importante en el diseño de la caché suele ser si el mecanismo de falla está alineado con los cambios comerciales.
Las modificaciones comunes incluyen:
- Utilice fallas impulsadas por eventos en lugar de depender únicamente de TTL;
- Agregue fluctuación aleatoria a TTL para evitar que las claves del punto de acceso caduquen al mismo tiempo;
- Introduzca el número de versión o la marca de tiempo en la clave para cambiar explícitamente la generación de datos;
- Permitir que se devuelvan valores antiguos durante un corto período de tiempo, pero que se actualicen de forma asincrónica en segundo plano en lugar de que todas las solicitudes regresen al origen juntas.
Lo principal aquí es que debe decidir cuándo aceptar datos antiguos, cuándo deben ser consistentes de inmediato y cuándo preferiría devolver el resultado de degradación en lugar de hacer estallar la base de datos principal. ** Esta es la estrategia de almacenamiento en caché y la tasa de aciertos es solo una sombra de ella.
Ampliar el TTL a menudo simplemente hace retroceder el problema.
He visto muchas “optimizaciones de caché” realizadas de esta manera: la base de datos en línea está bajo presión, por lo que el TTL se cambia de 5 minutos a 30 minutos y luego a 1 hora. Como resultado, la tasa de aciertos aumentó y la curva de la base de datos se volvió un poco plana, y el equipo anunció que la optimización se había completado.
Lo más peligroso de este enfoque es que es demasiado fácil parecer eficaz a corto plazo.
Porque la mayoría de los sistemas de indicadores son mejores para registrar “cuántas consultas se guardan” y no son buenos para registrar “cuántos datos erróneos se guardan”. Cuando más usuarios leen precios antiguos, configuraciones antiguas y permisos antiguos, las pérdidas a menudo no se reflejan inmediatamente en el panel de caché, sino que aparecerán más adelante en quejas, compensaciones, verificación manual y revisiones de accidentes.
Especialmente para los siguientes tipos de datos, a menudo es una mala idea ampliar el TTL de forma aproximada:
- Datos que afectarán la liquidación del importe;
- Datos que afectan los permisos y la visibilidad;
- Datos que no se actualizan con frecuencia, pero que deben converger lo más rápido posible una vez actualizados.
Para este tipo de datos, si la tasa de aciertos más alta se obtiene mediante el “reconocimiento retrasado de cambios”, se sobregira la precisión. **
La parte más difícil del almacenamiento en caché es limitar los errores
Una situación común es pensar en el almacenamiento en caché como “una capa adicional delante de la base de datos”. Esta comprensión no es errónea, pero es demasiado optimista.
El almacenamiento en caché en sistemas reales es una superficie de tensión que amplifica los defectos de diseño. Si la llave tiene un diseño demasiado grueso, el alcance del fallo será demasiado grande; si la clave tiene un diseño demasiado delgado, aumentará el uso de la memoria y la complejidad del mantenimiento; el ensamblaje de datos se coloca en la capa de caché y es fácil repetir los cálculos al regresar a la fuente; La caché local y la caché distribuida se apilan juntas y habrá una capa adicional de problemas de coherencia.
Así que dividiré la solución de almacenamiento en caché en dos preguntas para revisar:
- ¿Normalmente estás feliz o no?
- Cuando algo sale mal, ¿arrastrará otras partes del sistema?
La última pregunta suele ser más importante.
Una implementación de caché más confiable a menudo manejará explícitamente lo siguiente:
v, ok := cache.Get(key)
if ok && !v.SoftExpired() {
return v.Data
}
return singleflight.Do(key, func() any {
fresh := db.Load(id)
cache.Set(key, fresh, ttlWithJitter())
return fresh
})
Lo realmente valioso aquí son dos limitaciones:
- Cuando se devuelve la misma clave al origen, solo se permite que una solicitud llegue a la base de datos;
- La caducidad le da al sistema una ventana de actualización controlable.
Es posible que este tipo de diseño no necesariamente logre la mejor tasa de aciertos, pero puede reducir significativamente las tormentas de retorno y la amplificación instantánea. Sin fluctuaciones, el sistema se parece más a “desacelerarse” que a “colapsar”.
Un malentendido común: tratar la tasa de aciertos de caché como un KPI de equipo
Una vez que el porcentaje de acierto se convierte en un KPI, es fácil que los equipos trabajen en la dirección equivocada.
Porque la forma más sencilla de mejorar la tasa de aciertos suele ser mejorar los resultados estadísticos:
- Estirar TTL;
- Poner más datos que no deberían almacenarse en caché;
- Utilice teclas más gruesas para mezclar diferentes escenas;
- Dividir la interfaz para que sea compatible con el caché empeora la semántica empresarial.
Estas acciones pueden hacer que el gráfico se vea mejor, pero aumentarán otros problemas: la ventana de datos sucios será más larga, las fallas serán más difíciles, la resolución de problemas será más difícil, la memoria será más costosa y los límites del negocio serán borrosos.
Un enfoque más saludable es considerar el almacenamiento en caché junto con las siguientes métricas:
- La señorita P95/P99 tarda en volver a la fuente;
- Número de claves de puntos de acceso simultáneos de regreso a la fuente;
- Tasa de error y pico de la base de datos después de la invalidación del caché;
- El tiempo que tardan los datos en converger a nuevos valores después de la actualización;
- Cuántas rutas de código y acciones operativas adicionales se introducen para mantener la caché.
Sólo cuando se suman estos costos la tasa de aciertos tiene poder explicativo. Mirándolo solo, es demasiado fácil dejarse engañar.
Ejemplo contrario: en algunos escenarios, la tasa de aciertos debe ser lo más alta posible
No puedes simplemente decirlo hasta la muerte.
Si los datos son naturalmente estables, o simplemente un recurso inmutable, como archivos estáticos, configuraciones versionadas, contenido de distribución CDN y tablas de diccionario que rara vez cambian, entonces la tasa de aciertos es de hecho un objetivo muy importante. Porque en este tipo de escenario, lo “antiguo” no es un problema grave, la falla es relativamente simple y el camino de regreso a la fuente suele ser claro y controlable.
También existen algunos sistemas internos basados en herramientas donde la cantidad de datos no es grande, la escritura es poco frecuente y el costo comercial de las lecturas sucias ocasionales también es muy bajo. En este caso, una solución TTL simple probablemente sea la adecuada. A primera vista parece de alta gama, pero en realidad está más cerca de ser lo suficientemente barato.
Por lo tanto, este artículo está en contra de sacar la tasa de aciertos del contexto y utilizarla sola como prueba de si el caché es exitoso.
Resumen
Para juzgar si una solución de almacenamiento en caché es confiable, primero preguntaría: **¿Qué pasará cuando ocurra el fallo más costoso en este sistema? **
Si la respuesta es “un poco más lento, el sistema aún puede ser estable”, lo más probable es que el caché esté diseñado.
Si la respuesta es “la tasa de aciertos suele ser muy alta, pero una vez que falla, penetrará la base de datos principal y reducirá la precisión”, entonces es solo un peligro oculto que parece funcionar duro en momentos normales.
El almacenamiento en caché nunca se trata sólo de “poner los datos más cerca”. Lo que realmente pone a prueba es cómo afrontar los cambios, los fallos y los costes. Una tasa de aciertos alta significa que has hecho bien la primera mitad de la frase como máximo; es la segunda mitad de la oración la que determina si la estrategia vale la pena.
What to read next
Want more posts about Caching?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #Performance Optimization?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home