Almacenamiento en caché encadenado
Información general
Flujo de datos
Al enviar una página desde un servidor al explorador de un cliente, se atraviesan una multitud de sistemas y subsistemas. Si observa con atención, hay una serie de saltos que los datos deben llevar del origen al drenaje, cada uno de los cuales es un candidato potencial para el almacenamiento en caché.
Flujo de datos de una aplicación CMS típica
Comencemos nuestro recorrido con un fragmento de datos que se encuentra en un disco duro y que debe mostrarse en un explorador.
Hardware y sistema operativo
En primer lugar, la propia unidad de disco duro (HDD) tiene una caché integrada en el hardware. Segundo, el sistema operativo que monta el disco duro, utiliza memoria libre para almacenar en caché los bloques a los que se accede con frecuencia para acelerar el acceso.
Repositorio de contenido
El siguiente nivel es CRX o Oak AEM: la base de datos de documentos utilizada por los usuarios de la base de datos de documentos de. CRX y Oak dividen los datos en segmentos que se pueden almacenar en caché también para evitar un acceso más lento al disco duro.
Datos de terceros
La mayoría de las instalaciones web más grandes también tienen datos de terceros; datos procedentes de un sistema de información de productos, un sistema de gestión de relaciones con el cliente, una base de datos heredada o cualquier otro servicio web arbitrario. No es necesario extraer estos datos de la fuente cada vez que se necesitan, especialmente cuando se sabe que cambian con poca frecuencia. Por lo tanto, se puede almacenar en caché si no se sincroniza en la base de datos de CRX.
Nivel empresarial: aplicación/modelo
Normalmente, los scripts de plantilla no representan el contenido sin procesar proveniente de CRX a través de la API JCR. Lo más probable es que tenga una capa empresarial intermedia que combine, calcule o transforme datos en un objeto de dominio empresarial. Adivina qué: si estas operaciones son costosas, debe considerar almacenarlas en caché.
Fragmentos de marcado
El modelo ahora es la base para la renderización del marcado de un componente. ¿Por qué no almacenar también en caché el modelo procesado?
Dispatcher, CDN y otros proxies
Desactivado va la página HTML procesada a Dispatcher. Ya hemos hablado de que el principal propósito de Dispatcher es almacenar en caché las páginas de los HTML y otros recursos web (a pesar de su nombre). Antes de que los recursos lleguen al explorador, puede pasar un proxy inverso, que puede almacenar en caché y una CDN, que también se utiliza para el almacenamiento en caché. El cliente puede sentarse en una oficina que concede acceso a la web solo a través de un proxy, y ese proxy puede decidir almacenar en caché también para ahorrar tráfico.
Caché del explorador
Por último, pero no menos importante, el explorador también almacena en caché. Este es un recurso fácilmente ignorado. Sin embargo, es la caché más cercana y rápida que tiene en la cadena de almacenamiento en caché. Lamentablemente, no se comparte entre usuarios, pero entre distintas solicitudes de un usuario.
Dónde almacenar en caché y por qué
Esa es una larga cadena de cachés potenciales. Y todos hemos enfrentado problemas donde hemos visto contenido obsoleto. Pero teniendo en cuenta cuántas etapas hay, es un milagro que la mayor parte del tiempo esté funcionando.
Pero, ¿en qué parte de esa cadena tiene sentido almacenar en caché? ¿Al principio? ¿Al final? ¿En todas partes? Depende… y depende de un gran número de factores. Incluso dos recursos en el mismo sitio web podrían desear una respuesta diferente a esa pregunta.
Para darle una idea aproximada de qué factores podría tener en cuenta,
Tiempo de vida: si los objetos tienen un corto tiempo de vida inherente (los datos de tráfico pueden tener un tiempo de vida inferior al de los datos meteorológicos), puede que no valga la pena almacenarlos en caché.
Costo de producción - Cuánto cuesta (en términos de ciclos de CPU y E/S) la reproducción y entrega de un objeto. Si es barato, el almacenamiento en caché podría no ser necesario.
Tamaño: los objetos grandes requieren más recursos para almacenarse en caché. Ese podría ser un factor limitante y debe sopesarse en relación con los beneficios.
Frecuencia de acceso: si no se accede a los objetos con mucha frecuencia, el almacenamiento en caché podría no ser eficaz. Simplemente quedarían obsoletos o se invalidarían antes de que se acceda a ellos por segunda vez desde la caché. Estos elementos simplemente bloquearían los recursos de memoria.
Acceso compartido: los datos que usen más de una entidad deben almacenarse en la caché más arriba en la cadena. En realidad, la cadena de almacenamiento en caché no es una cadena, sino un árbol. Más de un modelo podría utilizar un fragmento de datos del repositorio. Estos modelos, a su vez, los puede utilizar más de un script de procesamiento para generar fragmentos de HTML. Estos fragmentos se incluyen en varias páginas que se distribuyen a varios usuarios con sus cachés privadas en el explorador. Así que "compartir" no significa compartir entre personas solamente, sino entre piezas de software. Si desea encontrar una caché "compartida" potencial, solo tiene que rastrear el árbol hasta la raíz y encontrar un antecesor común, ahí es donde debe almacenar en caché.
Distribución geoespacial: si los usuarios están distribuidos en todo el mundo, el uso de una red distribuida de cachés puede ayudar a reducir la latencia.
Ancho de banda y latencia de la red - Hablando de latencia, ¿quiénes son sus clientes y qué tipo de red utilizan? ¿Tal vez sus clientes son clientes móviles en un país subdesarrollado que utilizan una conexión 3G de teléfonos inteligentes de generación más antigua? Considere la posibilidad de crear objetos más pequeños y almacenarlos en caché en las cachés del explorador.
Esta lista no es muy completa, pero creemos que ya entendieron la idea.
Reglas básicas para el almacenamiento en caché encadenado
De nuevo: el almacenamiento en caché es difícil. Compartimos algunas reglas básicas que hemos extraído de proyectos anteriores y que pueden ayudarle a evitar problemas en su proyecto.
Evitar el almacenamiento en caché doble
Cada una de las capas introducidas en el último capítulo proporciona algún valor en la cadena de almacenamiento en caché. Ahorrando ciclos informáticos o acercando los datos al consumidor. No es incorrecto almacenar en caché un fragmento de datos en varias etapas de la cadena, pero siempre debe tener en cuenta cuáles son los beneficios y los costes de la siguiente etapa. Almacenar en caché una página completa en el sistema de Publish no suele proporcionar ningún beneficio, ya que esto ya se hace en Dispatcher.
Combinación de estrategias de invalidación
Existen tres estrategias básicas de invalidación:
- TTL, Tiempo de vida: Un objeto caduca después de una cantidad de tiempo fija (por ejemplo, "2 horas a partir de ahora")
- Fecha de caducidad: El objeto caducará a una hora futura definida (por ejemplo, "5:00 p.m. del 10 de junio de 2019")
- Basado en evento: El objeto se invalida explícitamente por un evento que se produjo en la plataforma (por ejemplo, cuando se cambia y activa una página)
Ahora puede utilizar diferentes estrategias en diferentes capas de caché, pero hay algunas "tóxicas".
Invalidación basada en evento
Invalidación basada en evento puro: invalidar de la caché interna a la capa externa
La invalidación pura basada en eventos es la más fácil de comprender, la más fácil de hacer correctamente en teoría y la más precisa.
En pocas palabras, las cachés se invalidan una por una después de que el objeto haya cambiado.
Solo tiene que tener en cuenta una regla:
Invalidar siempre desde la caché interna a la caché externa. Si invalidó primero una caché externa, podría volver a almacenar en caché el contenido obsoleto de una caché interna. No realice ninguna suposición en el momento en que una caché vuelva a estar fresca: asegúrese de que lo está. Lo mejor es activar la invalidación de la caché externa después de para invalidar la caché interna.
Ahora, esa es la teoría. Pero en la práctica hay una serie de problemas. Los eventos deben distribuirse, posiblemente a través de una red. En la práctica, esto hace que sea el esquema de invalidación más difícil de implementar.
Automático: Curación
Con la invalidación basada en eventos, debe tener un plan de contingencia. ¿Qué sucede si se pasa por alto un evento de invalidación? Una estrategia sencilla podría ser invalidar o purgar después de una cierta cantidad de tiempo. Por lo tanto, es posible que se haya perdido ese evento y ahora ofrezca contenido obsoleto. Sin embargo, los objetos también tienen un TTL implícito de varias horas (días) únicamente. Así que eventualmente el sistema se cura a sí mismo.
Invalidación pura basada en TTL
invalidación basada en TTL sin sincronizar
Ese también es un esquema bastante común. Se apilan varias capas de cachés, cada una con derecho a servir un objeto durante una cierta cantidad de tiempo.
Es fácil de implementar. Desafortunadamente, es difícil predecir la vida útil efectiva de un fragmento de datos.
Caché externa que prolonga la vida útil de un objeto interno
Consideremos la ilustración anterior. Cada capa de almacenamiento en caché introduce un TTL de 2 minutos. Ahora - el TTL general debe 2 min también, ¿verdad? No del todo. Si la capa exterior recupera el objeto justo antes de que quede obsoleto, la capa exterior en realidad prolonga el tiempo de vida efectivo del objeto. El tiempo de vida efectivo puede estar entre 2 y 4 minutos en ese caso. Considere que estuvo de acuerdo con su departamento comercial, un día es tolerable y tiene cuatro capas de cachés. El TTL real en cada capa no debe ser superior a seis horas… aumentando la tasa de fallos de caché…
No estamos diciendo que sea un mal plan. Deberías saber sus límites. Y es una buena y fácil estrategia para empezar. Solo si el tráfico del sitio aumenta, puede considerar una estrategia más precisa.
Sincronizando la hora de invalidación estableciendo una fecha específica
Invalidación basada en fecha de vencimiento
Se obtiene una vida útil efectiva más predecible, si se configura una fecha específica en el objeto interno y se propaga a las cachés externas.
Sincronizando fechas de caducidad
Sin embargo, no todas las cachés pueden propagar las fechas. Y puede volverse desagradable, cuando la caché externa agrega dos objetos internos con diferentes fechas de caducidad.
Combinación de invalidación basada en eventos y en TTL
Combinar estrategias basadas en eventos y basadas en TTL
AEM También un esquema común en el mundo de la es utilizar la invalidación basada en eventos en las cachés internas (por ejemplo, cachés en memoria donde los eventos se pueden procesar en tiempo casi real) y cachés basadas en TTL en el exterior, donde tal vez no tenga acceso a la invalidación explícita.
AEM En el mundo de los recursos, tendría una caché en memoria para objetos empresariales y fragmentos de HTML en los sistemas de Publish, que se invalidará cuando cambien los recursos subyacentes y propagará este evento de cambio al distribuidor, que también funciona en función de eventos. Por delante tendría, por ejemplo, una CDN basada en TTL.
Tener una capa de almacenamiento en caché (corto) basado en TTL delante de una Dispatcher podría suavizar eficazmente un pico que generalmente se produciría después de una invalidación automática.
Combinación de TTL e invalidación basada en eventos
Tóxico: mezcla de TTL e invalidación basada en eventos
Esta combinación es tóxica. Nunca coloque una caché basada en eventos después de un TTL o una caché basada en caducidad. ¿Recuerdan el efecto derrame que tuvimos en la estrategia de "TTL puro"? El mismo efecto se puede observar aquí. Solo que el evento de invalidación de la caché externa ya se ha producido puede que no vuelva a ocurrir, nunca más, esto puede expandir la vida útil del objeto en caché hasta el infinito.
Combinación basada en TTL y en eventos: desbordamiento hasta el infinito
Almacenamiento en caché parcial y almacenamiento en caché en memoria
Puede conectarse al escenario del proceso de renderización para añadir capas de almacenamiento en caché. Desde obtener objetos de transferencia de datos remotos o crear objetos empresariales locales hasta almacenar en caché el marcado procesado de un solo componente. Dejaremos las implementaciones concretas en un tutorial posterior. Pero tal vez ya tiene pensado implementar algunas de estas capas de almacenamiento en caché. Así que lo menos que podemos hacer aquí es introducir los principios básicos… y los problemas.
Palabras de advertencia
Respetar control de acceso
AEM Las técnicas descritas aquí son bastante poderosas y se debe tener en cada caja de herramientas de desarrollador de la aplicación de herramientas para desarrolladores de la aplicación de herramientas de la aplicación para desarrolladores de la aplicación de herramientas de la aplicación de herramientas para desarrolladores de la aplicación de herramientas. Pero no te emociones demasiado, úsalos sabiamente. Almacenar un objeto en una caché y compartirlo con otros usuarios en solicitudes de seguimiento significa eludir el control de acceso. Esto no suele ser un problema en los sitios web públicos, pero puede serlo cuando un usuario necesita iniciar sesión antes de obtener acceso.
Considere la posibilidad de almacenar el marcado de HTML de un menú principal de sitios en una memoria caché en memoria para compartirlo entre varias páginas. En realidad, este es un ejemplo perfecto para almacenar HTML procesados parcialmente, ya que la creación de una navegación suele ser costosa, ya que requiere atravesar muchas páginas.
No comparte la misma estructura de menús entre todas las páginas, sino también con todos los usuarios, lo que la hace aún más eficaz. Pero espere… pero tal vez haya algunos elementos en el menú que están reservados únicamente para un determinado grupo de usuarios. En ese caso, el almacenamiento en caché puede ser un poco más complejo.