How to choose between cache-aside, read-through, write-through, client-side, and distributed caching strategies Como hemos mencionado en los últimos post, estamos encantados de que Pekka Enberg decida escribir Y estamos orgullosos de patrocinar tres capítulos de él. ¿Por qué guardar datos? Un libro sobre la latencia Obtener el extracto del libro Latency PDF Obtener el extracto del libro Latency PDF Obtener el extracto del libro Latency PDF Además, Pekka acaba de compartir las tomas clave de ese libro en una (Actualmente disponible a petición) Masterclass sobre la construcción de aplicaciones de baja latencia Continuemos con nuestro El libro contiene extractos con más del capítulo de caché de Pekka. Está reimpreso aquí con el permiso del editor. Latencia * El Al agregar la caché a su aplicación, primero debe considerar su estrategia de caché, que determina cómo se leen y escriben desde la caché y el almacenamiento de seguridad subyacente, como una base de datos o un servicio. En otras palabras, cuando su aplicación mira un valor de la caché, pero el valor no está allí o ha expirado, la estrategia de caché manda si es su aplicación o la caché que recupera el valor de la tienda de respaldo. Como de costumbre, diferentes estrategias de caché tienen diferentes compromisos sobre la latencia y la complejidad, así que vamos a entrar en él. Caché Aside Caché Cuando hay un golpe de caché, la latencia de acceso a los datos está dominada por la latencia de comunicación, que suele ser pequeña, ya que puede obtener una caché cerca en un servidor de caché o incluso en el espacio de memoria de su aplicación. Sin embargo, cuando hay una falta de caché, con caché-side caching, la caché es una tienda pasiva actualizada por la aplicación. Es decir, la caché sólo reporta una falta y la aplicación es responsable de recoger datos de la tienda de respaldo y actualizar la caché. La Figura 1 muestra un ejemplo de cache-side caching en acción.Una aplicación mira un valor de una caché por una clave de cache, que determina los datos en los que la aplicación está interesada. Si la clave existe en la caché, la caché devuelve el valor asociado con la clave, que la aplicación puede usar. Sin embargo, si la clave no existe o ha expirado en la caché, tenemos una falta de caché, que la aplicación tiene que manejar. Supongamos que está cacheando la información del usuario y usando el ID del usuario como la clave de búsqueda. En ese caso, la aplicación realiza una consulta por el ID del usuario para leer la información del usuario de la base de datos. La información del usuario devuelta de la base de datos se transforma luego en un formato que puede almacenar en la caché. Luego, la caché se actualiza con el ID del usuario como la clave de caché y la información como el valor. Por ejemplo, una forma típica de realizar este tipo de caché es transformar la información del usuario devuelta de la base de datos en JSON y almacenarla en la caché. El cache-side caching es popular porque es fácil configurar un servidor de cache como Redis y usarlo para cachear consultas de base de datos y respuestas de servicio. Con el cache-side caching, el servidor de cache es pasivo y no necesita saber qué base de datos utiliza o cómo los resultados se mapean a la cache. Es su aplicación haciendo toda la gestión de cache y transformación de datos. En muchos casos, el cache-side caching es una forma sencilla y efectiva de reducir la latencia de la aplicación.Puede ocultar la latencia de acceso a la base de datos al tener la información más relevante en un servidor de caché cercano a su aplicación. Por ejemplo, si tiene varios lectores simultáneos que están buscando una clave en la caché, debe coordinar en su aplicación cómo manejar los fallos de caché simultáneos; de lo contrario, puede terminar con múltiples accesos a bases de datos y actualizaciones de caché, lo que puede resultar en búsquedas posteriores de caché que devuelven valores diferentes. Sin embargo, con el cache-side caching, pierdes el soporte de transacciones porque el cache y la base de datos no se conocen entre sí, y es responsabilidad de la aplicación coordinar las actualizaciones a los datos. Finalmente, el cache-side caching puede tener una latencia de cola significativa porque algunas búsquedas de caché experimentan la latencia de lectura de la base de datos en una falta de caché. Es decir, aunque en el caso de un golpe de caché, la latencia de acceso es rápida porque viene de un servidor de caché cercano; las búsquedas de caché que experimentan una falta de caché son sólo tan rápidas como el acceso a la base de datos. Leer a través del caching La caché de lectura es una estrategia en la que, a diferencia de la caché de lado, la caché es un componente activo cuando hay una falta de caché. Cuando hay una falta de caché, una caché de lectura intenta leer automáticamente un valor para la clave de la tienda de respaldo. La latencia es similar a la caché de lado, aunque la latencia de recuperación de la tienda de respaldo es de la caché a la tienda de respaldo, no de la aplicación a la tienda de respaldo, que puede ser menor, dependiendo de su arquitectura de implementación. La aplicación realiza una búsqueda de caché en una clave, y si hay una falta de caché, la caché realiza una lectura a la base de datos para obtener el valor para la clave. La caché luego se actualiza y devuelve el valor a la aplicación. Desde un punto de vista de la aplicación, una falta de caché es transparente porque la caché siempre devuelve una clave si existe, independientemente de si hubo una falta de caché o no. Read-through caching es más complejo de implementar porque una caché necesita poder leer el almacenamiento de seguridad, pero también necesita transformar los resultados de la base de datos en un formato para la caché. Por ejemplo, si la caché de seguridad es un servidor de base de datos SQL, necesita convertir los resultados de la consulta en un formato JSON o similar para almacenar los resultados en la caché. Sin embargo, debido a que la caché coordina las actualizaciones y la base de datos se lee con la caché de lectura, puede dar garantías transaccionales a la aplicación y garantizar la coherencia en los fallos de caché simultáneos. Además, aunque una caché de lectura es más compleja desde el punto de vista de la integración de la aplicación, elimina la complejidad de la gestión de caché de la aplicación. Por supuesto, la misma advertencia de la latencia de cola se aplica a las cachés de lectura como lo hacen a la caché de lado. Una excepción: como componentes activos, las cachés de lectura pueden ocultar mejor la latencia con, por ejemplo, la caché de refresco. Aquí, la caché actualiza de forma asíncrona la caché antes de que los valores expiren – por lo tanto, ocultando la latencia de acceso de la base de datos de las aplicaciones completamente cuando un valor está en la caché. Escribir a través del caching El cache-side y el cache-through son estrategias en torno a las lecturas de cache, pero a veces también quieres que el cache soporte las escrituras. En tales casos, el cache proporciona una interfaz para actualizar el valor de una clave que la aplicación puede invocar. En el caso del cache-side, la aplicación es la única que comunica con el repositorio y, por lo tanto, actualiza el cache. Sin embargo, con el cache-through, hay dos opciones para tratar con las escrituras: el cache-through y el cache-back. El cache de escritura es una estrategia en la que una actualización de la caché se propaga inmediatamente a la tienda de backup. Cada vez que se actualiza una caché, la caché actualiza sincronamente la caché con el valor de escritura. La latencia de escritura de la caché de escritura está dominada por la latencia de escritura a la caché, que puede ser significativa. Como se muestra en la Figura 3, una aplicación actualiza una caché utilizando una interfaz proporcionada por la caché con una clave y un par de valores. La caché actualiza su estado con el nuevo valor, actualiza la base de datos con el nuevo valor y espera que la base de datos comprometa la actualización hasta que reconozca la actualización de la caché a la aplicación. El cache de escritura a través tiene como objetivo mantener la caché y el almacenamiento de respaldo sincronizados. Sin embargo, para las cachés no transaccionales, la caché y el almacenamiento de respaldo pueden estar fuera de sincronización en presencia de errores. Por ejemplo, si la escritura a la caché tiene éxito, pero la escritura a la tienda de respaldo falla, las dos estarán fuera de sincronización. Por supuesto, una caché de escritura a través puede proporcionar garantías transaccionales al negociar alguna latencia para asegurarse de que la caché y la base de datos estén actualizadas o ninguna de ellas. Al igual que con una caché de lectura, la caché de escritura asume que la caché puede conectarse a la base de datos y transformar un valor de caché en una consulta de base de datos. Por ejemplo, si está cacheando datos de usuario donde el ID de usuario sirve como la clave y un documento JSON representa el valor, la caché debe ser capaz de transformar la representación JSON de la información del usuario en una actualización de la base de datos. Con la caché de escritura, la solución más simple a menudo es almacenar el JSON en la base de datos. La principal desventaja de la caché de escritura es la latencia asociada con las actualizaciones de caché, que es esencialmente equivalente a la latencia de comisión de la base de datos. Escribir detrás del cache La estrategia de caché de escritura trasera actualiza inmediatamente la caché, a diferencia de la caché de escritura trasera, que evita las actualizaciones de la base de datos. En otras palabras, con la caché de escritura trasera, la caché puede aceptar múltiples actualizaciones antes de actualizar el almacenamiento de seguridad, como se muestra en la Figura 4, donde la caché acepta tres actualizaciones de caché antes de actualizar la base de datos. La latencia de escritura de una caché de escritura trasera es menor que con la caché de escritura trasera porque la caché se actualiza de forma asíncrona. Es decir, la caché puede reconocer la escritura inmediatamente a la aplicación, lo que resulta en una escritura de baja latencia, y luego realizar la actualización de la caché de escritura trasera en el fondo. Sin embargo, la desventaja de la caché de escritura trasera es que pierdes el soporte de transacción porque la caché ya no puede garantizar que la caché y la base de datos estén en sincronía. Además, la caché de escritura trasera puede reducir la durabilidad, lo que es la garantía de que no pierdes datos. Cliente de Caché Una estrategia de caché del lado del cliente significa tener la caché en la capa del cliente dentro de su aplicación.Aunque los servidores de caché como Redis utilizan la caché en memoria, la aplicación debe comunicarse a través de la red para acceder a la caché a través del protocolo Redis. Si la aplicación es un servicio que se ejecuta en un centro de datos, un servidor de caché es excelente para el caché porque el giro de red dentro de un centro de datos es rápido, y la complejidad del caché está en el propio caché. Sin embargo, la latencia de la última milla todavía puede ser un factor significativo en la experiencia del usuario en un dispositivo, por lo que el caché del lado del cliente es tan lucrativo. Con el caché del lado del cliente, una combinación de caché de lectura y escritura es óptima desde el punto de vista de la latencia porque tanto las lecturas como las escrituras son rápidas. Por supuesto, su cliente generalmente no podrá conectarse directamente a la base de datos, sino que accede a la base de datos indirectamente a través de un servidor proxy o un servidor API. Para muchas aplicaciones que necesitan cache de lado del cliente de baja latencia, el enfoque local-first a la replicación puede ser más práctico.Pero para el cache de lectura simple, el cache del lado del cliente puede ser una buena solución para lograr una latencia baja.Por supuesto, el cache del lado del cliente también tiene un compromiso: puede aumentar el consumo de memoria de la aplicación porque necesita espacio para la caché. Caché distribuido Hasta ahora, sólo hemos hablado de la caché como si existiera una sola instancia de caché. Por ejemplo, usa una caché en la aplicación o un servidor Redis único para cacher consultas de una base de datos PostgreSQL. Sin embargo, a menudo necesita copias múltiples de los datos para reducir la latencia geográfica en diferentes ubicaciones o escalar para acomodar su carga de trabajo. Con tal caché distribuido, tienes numerosas instancias de caché que funcionan independientemente o en un clúster de cachés. Con caché distribuido, tienes muchas de las mismas complicaciones y consideraciones que con las discutidas en el Capítulo 4 sobre replicación y en el Capítulo 5 sobre partición. Con caché distribuido, no quieres encajar todos los datos cachés en cada instancia, sino tener datos cachés particionados entre los nodos. De la misma manera, puedes replicar las particiones en varias instancias para una alta disponibilidad y una latencia de acceso reducida. En general, el caché distribuido es una intersección de los beneficios y problemas del caché, la partición y la replicación, así que tenga cuidado si va con eso. * El Para seguir leyendo, desde ScyllaDB o . Descarga el extracto del capítulo 3 de Latency gratis Comprar el libro completo de Manning Más sobre Cynthia Dunlop Cynthia es directora senior de estrategia de contenido en ScyllaDB. Ha estado escribiendo sobre desarrollo de software e ingeniería de calidad durante más de 20 años.