domingo, enero 12, 2014

Cache y estrategias, parte 1

Cache, en una aplicación medianamente escalable, ni que decir en una altamente escalable, la cache es un elemento clave en el desempeño y tiempo de respuesta. Regularmente utilizamos la cache de una manera muy simple, basado en un conjunto de entradas determinamos si el objeto se encuentra en cache, si no se encuentra ejecutamos la lógica de negocios para obtener la información y volver a introducirla en la cache para  futuros llamados. Regularmente este esquema es lo suficientemente bueno para la mayoría de sistemas de tamaño regular, pero un sistema con muchas consultas, un nivel de concurrencia mayor, etc, debemos empezar analizar el comportamiento de nuestra memoria y determinar las mejores estrategias de almacenamiento cache.

Que cachear, supercache

En lo personal creo que una estrategia cache muy eficaz (sin embargo no siempre eficiente) es almacenar a fuerza bruta si es posible toda la información en memoria, es decir si tenemos un cluster de cache con memoria RAM lo suficientemente grande como para que  podamos guardar por ejemplo el catalogo de productos, mi recomendación sería guardar todo ahí, sistemas como los de redes sociales, suelen tener clusters gigantes con información guardada en memoria y hace que las aplicaciones sean más rápidas, en este esquema por lo regular solo tenemos que tener cuidado con la invalidación de la cache (cuando algo cachado cambia, debe eliminarse el registro actual de la cache para que  obtenga los últimos cambios). Podríamos reducir entonces la estrategia a, si tiene mucho espacio en memoria, simplemente úselo.

Los más populares

En algunos modelos de negocios conocemos cuales objetos son los más populares, tanto por conteo estadísticos como heurísticas de negocio; tomemos por ejemplo el caso de un sistema de comercio electrónico, un agente de negocios puede conocer de antemano cuales productos son los más vendidos, más populares, etc. Así pues con este conocimiento podríamos levantar un listado de productos y al inicio de la aplicación hacer un “warm up” de la cache con estos objetos, adicionalmente si no se tienen muchas áreas de cache yo recomiendo crear estos objetos en un área aparte del resto de productos comúnmente cachados con el fin de monitorear en el futuro el comportamiento de estos objetos en cache.

La segunda estrategia siempre dentro del esquema de los más populares es calcularla programáticamente mediante el análisis estadístico de la cache (sencillo cuales productos pasan más tiempo en memoria a razón de mayor cantidad de hits), así pues podemos guardar esta lista en algún mecanismo de persistencia y cuando se requiera o cuando se inicia la aplicación solicitar que se caliente la cache con estos elementos también.

Por último se me ocurre una tercera estrategia, esta de la mano de la heurística; un producto nuevo puede de pronto volverse popular (incluso uno impopular puede volverse popular), regularmente la gente de marketing tiene métricas sobre sus expectativas de ventas, por ejemplo una promoción (un producto nuevo), un sale (productos que se van a colocar en oferta), un combo (grupo de productos a mejor precio), producto posicionado (un producto que se va poner por ejemplo en la página de home page o alguna otra página de alto alcance, etc). Estas acciones tienen un motivo claramente conocido por marketing y en conjunto, se pueden crear listas de productos para ser cachados previamente y así hacer la aplicación mas rápida y eficiente (cache implica menos tiempo de CPU, I/O etc), ante la probabilidad de mayores consultas sobre estos objetos.

Impopulares y filtros

Regularmente dependiendo de las facilidades de hardware con que contamos (como dijimos antes si tiene mucha memoria y puede cacharlo todo, simplemente hágalo), filtramos los objetos que vamos a introducir a memoria. La estrategia más sencilla es limitar el tamaño de los  objetos, por ejemplo nada mayor a 100kb o un megabyte, etc. Esto con el motivo de no saturar nuestra cache con objetos gigantes de manera muy rápida.

Si bien es cierto tener algo en cache ahorra tiempo de CPU y regularmente I/O, latencia y por ende tiempo de respuesta al usuario, pero también debemos tener en cuenta que si nuestro espacio de memoria para cache es limitado debemos evitar incluir objetos que consumirán memoria en forma de paracito, me explico; la idea de la cache es almacenar un objeto en ella, de tal manera que reciba al menos un hit antes de que este expire y sea eliminado de la cache (depende de la estrategia pero regularmente por prioridad o TTL, un objeto es eliminado de la cache cuando no es invocado por mucho tiempo y la cache está llena o cuando se vence un el tiempo designado en TTL), así pues agregar objetos a la cache que nunca son leídos resultará en una mala gestión de nuestros recursos de hardware.

Por ende, lo que se propone es identificar que objetos son los más impopulares y filtrar su adicción a la cache, por ejemplo los frameworks de cache regularmente proporcionan estadísticas acerca del comportamientos de los entries, pero nosotros podemos hacer un servicio que sea el helper mediante el cual se entra a la cache y guardar estadísticas propias acerca de que objetos se llaman y hacen hit, cuales se llaman y no hacen hit y así determinar cuáles son populares o no, o inclusive determinar si el tiempo de TTL para un objeto debe ser mayor, por ejemplo si tenemos un TTL parejo de 10 minutos y ciertos objetos son invocados cada 15 minutos, entonces estos vivirán 10 minutos en cache, serán eliminados pasados esos 10 minutos, para que 5 minutos después sean agregados de nuevo en la cache de forma infortunada.

Así pues, tendríamos implementados sobre la capa de abstracción de cache, una capa de estadísticas y otra de filtrado que nos ayude a determinar el comportamiento de los objetos en la cache.
Como vemos, existen algunas alternativas para hacer que nuestra estrategia de cache sea más asertiva y eficiente, mas adelante espero presentar un diagrama de clases e implementaciones de cómo lograr algunas de estas para que puedan darse una idea más clara de cómo implementarlas.

Pura vida,
J

1 comentario:

Naturaprint Naturaprint dijo...

imprenta online ecologica
http://www.naturaprint.es