Mi granito de java: Java Cache
Mostrando entradas con la etiqueta Java Cache. Mostrar todas las entradas
Mostrando entradas con la etiqueta Java Cache. Mostrar todas las entradas

jueves, 16 de junio de 2011

¿Cual es el mejor Java Cache?

Para hacerla corta...Infinispan. Para hacerla larga y ver que pruebas hicimos para sacar esa conclusión, leer lo que sigue a continuación.

Hemos realizado diverso tipos de pruebas con los caches más conocidos para que se tenga una mejor visión a la hora de seleccionar una alternativa.

Algunas de las siguientes pruebas se realizaron con el framework CacheBenchFwk en su version 1.0.0 y otras se hicieron con una aplicación desarrollada especialmente para estas pruebas, para poder tener una vista mas detallada sobre las ventajas de esta herramienta.

Las pruebas con el CacheBenchFwk las hemos realizado con las siguientes herramientas:
  • Infinispan 4.0.0
  • Jboss Cache 3.2.2GA
  • EHCache 1.7.2
Y las pruebas desarrolladas por nosotros las hicimos con las siguientes librerías en su versión FINAL:
  • Infinispan 4.1.0
  • Jboss Cache 3.2.5GA
  • EHCache 2.2.0


Las pruebas fueron realizadas con las siguiente configuracion:
  • Linux Ubuntu 10.04
  • Total memoria RAM: 4 Gigas.
  • Procesador: 4 procesadores Intel Atom 330 1.6 Ghz.
  • JDK version "1.6.0_20" 64-Bit con los parametros -Xms1g -Xmx1g
  • CacheBenchFwk 1.0.0
  • Pruebas en modo standalone con 25 concurrencias usando Strings generados aleatoriamente tanto para valores como para las claves generando 1 kb de carga por cada entrada.
  • Las pruebas no locales fueron hechas en una red local con 3 nodos de iguales características a las descriptas anteriormente.
  • Configuraciones de las distintas tecnologias estan por default. 


Pruebas locales.

En los siguientes graficos de performance se ven dos barras verticales para Infinispan como para JbossCache. Cada una se corresponde con un tipo de Isolation level Read Commited y Repeatable Read.

1) Pruebas de Stress
Carga de datos


Lectura de datos

2) Pruebas de escritura y lectura simples

Los tiempos son tan bajos que Infinispan no aparece en la grafica.

Como se puede apreciar en los graficos anteriores Infinispan es superior a Jboss Cache y EHCache, obteniendo los tiempos mas bajos tanto en escritura como lectura de datos.

En el caso de la pruebas de stress, estan fueron hechas con los distintos caches como si funcionaran unicamente en un servidor dedicado exclusivamente para cache. Si bien la tecnologia con la que se hicieron las pruebas no son las de un servidor, son aproximados los resultados. Las pruebas de stress demuestran que en el caso de que se quiera montar un servidor para uso exclusivo de cache Infinispan es una excelente opción, ya que en la pruebas se uso concurrencia simulando las distintas peticiones que se pueden realizar. Estas pruebas se realizaron como unico nodo, pero Infinispan se puede usar en modo cluster lo cual permitiria una mayor disponibilidad de datos y ser escalable, pudiendo elegir el modo en que se repliquen los datos(en cada nodo una copia o una parte de esta).

Por otro lado las pruebas simples fueron hechas con una aplicación simple desarrollada por Guillermo y por mí para demostrar la performance de cada cache en un modo de uso local contra una aplicación. Las pruebas, como se ve en los graficos, volvieron a dar a Infinispan como el más rapido. Estos resultados por ejemplo nos sirven a la hora de decidir con que cache de segundo nivel poner a funcionar Hibernate.



Pruebas no locales.

Dado que Infinispan fue un amplio ganador con respecto al resto, decidimos ampliar sus pruebas y realizar un testeo con varios nodos en red para ver si decrecía su rendimiento de alguna manera. Estas pruebas tuvieron las siguientes características:
  • Las pruebas se realizaron el con el cliente Hot Rod y en modo embebido, debido a que son las dos mejores maneras de usar Infinispan en un entorno con Java.
  • Para funcionar en modo cluster Infinispan usa Jgroups con las configuraciones TCP como para UDP.

Vamos a hacer una breve explicación de los dos modos:
1) Modo embebido.

La configuración en este modo es secilla, puede ser declarativa o programatica. Con esto podemos levantar varios nodos, pero en cada uno de estos debemos poner nuestra aplicación con Infinispan embebido. Si bien la configuracion es sencilla esto tiene desventajas:

  • Alto consumo de recursos.
  • Tiempo en inicializar Infinispan depende de la cantidad de datos que maneje el cache en ese momento.
  • Bloqueo de acceso al resto de las instancias al agregar nuevos nodos, debido que estos son lentos en levantar.
  • Para agregar un nuevo nodo debo deployar la aplicación en este.


2) Hot Rod Client
Esta manera de utilizar Infinispan resulta mas sencilla, rapido y performante que la embebida. Lo que se hizo fue levantar los nodos de la siguiente manera:

./startServer.sh -r hotrod -l 192.168.254.66 -c config.xml -p 11311 -o 192.168.254.66 -x 11311


Una vez con todos los nodos levantados, estos ya se estaban mandando mensajes entre sí. Luego levantamos la aplicación configurando la ip de un solo nodo y enseguida reconocio el resto y creo un pool de conexiones para cada uno. El codigo usado fue el siguiente:




Las pruebas con este cliente fueron mas que satisfactorias, ya que el cliente detectaba cuando se agregaba un nodo o se bajaba uno del cluster. Esto no afectaba a su performance. Si bien este cliente hay algunas operaciones que no soporta como las queries sobre el cache su manejo del cluster compensa.

¿Que aprendimos de las pruebas realizadas?


Al realizar las pruebas en modo embebido y con el cliente Hot Rod, se recomienda ampliamente el uso del cliente Hot Rod en un entorno Java, ya que este maneja de manera mas eficiente el cluster:
  • Detecta automáticamente cambios en la topología del cluster.
  • Al agregar nuevos nodos resulta es más rapido con el cliente Hot Rod que de manera embebida.
  • Usa lo que se llama smart routing para mayor velocidad de respuesta.
  • Se puede controlar el pool de conexiones con el cluster.
  • Al levantar el cliente este empieza a detectar los posibles nodos del cluster en la red local.
  • Muy configurable.

Conclusión.

Infinispan es un producto opensource de JBoss y se ha nutrido de la experiencia de Jboss Cache (una librería). Es una solución que nos permite crear enormes estructuras de datos distribuidas y altamente concurrentes almacenadas en la memoria RAM de múltiples nodos de un cluster.

Hemos podido observar que Infinispan es altamenta escalable, configurable y sencilla de utilizar. Asimismo, su rendimiento suele ser superior en casi todos los aspectos con respecto a sus competidores.

Infinispan no presentó problemas para realizar pruebas en máquinas distribuídas y su velicidad se ha mantenido constante en las diversas pruebas. Es un producto áltamente recomendable.

Este post es una adaptación de un informe que hice junto a Guillermo Kessler

Infinispan

Infinispan es una plataforma open source de manejo de Cache. Es similar a otras herramientas conocidas en el mercado como EHCache, JBoss Cache o Coherence.
Cabe aclarar que siendo una herramienta de Jboss, no es una improvisación, sino que el proyecto creció nutriendose de la experienca de JBoss Cache. De todas maneras, son herramientas diferentes, sin relación alguna. La gran diferencia entre ambas es que Jboss Cache es una librería y infinispan es una plataforma mucho mas completa, con herramientas GUI y posibilidad de distribuirla en miles de servidores/nodos.
Se puede bajar de: http://www.jboss.org/infinispan.

Sus características son:
  • Memoria masiva y alta disponibilidad: si bien es posible utilizar infinispan de manera local, su fuerte es el trabajo distribuìdo. No sólo se limita a que cada servidor es una copia de otro (como Jboss Cache), también es posible realizar realizar una distribución de la información en los diferentes servidores.
  • Escalabilidad: dado que es una plataforma distribuida es muy simple lograr que sea escalable. Se puede acoplar tantas instancias como se deseen y no existe impedimento hasta donde se quiera crecer con la capacidad del Cache.
  • Datos distribuidos: su algoritmo de hashing permite que sus datos distribuidos se recuperen de manera veloz y sin generar tráfico en la red.
  • Persistencia: posee varias formas para guardar los datos en el disco duro, que van desde JDBC hasta archivos planos.
  • Lenguajes varios: no sólo es posible trabajar con Java, también es posible utilizar varios lenguajes más como PHP, Python, Ruby, C, etc.
  • Administración: es simple de administrar y posee herramientas GUI para realizar estadísticas.

Configuración del Cache.

Es posible realizar una configuración declarativa, basada en XML o bien a nivel programación. Por otro lado, se puede configurar como default o Global, siendo esta última un cache compartido entre varias instancias.
Si se tiene una configuración previa con otra herramienta de cache, existen scripts que automatizan la migración hacia infinispan desde:
  • EHCache 1.x
  • JBoss Cache 3.x
  • Coherence 3.x

Tiene muchas facilidades para lockear objetos, sincronizar el cache, limpiarlo o hasta indexarlo de diversas formas. Es altamente configurable.


Ejemplo.



Cache Loaders

Un Cache Loader es la conexión que se mantiene contra una herramienta de persistencia de datos. Dicho loader es el encargado de guardar los datos para su posterior persistencia y obtener los datos cuando estos no se encuentren en el cache.
Infinispan posee muchas formas de configuración de cache loaders, de hecho, se puede configurar más de uno al mismo tiempo para que trabajen en cadena. Asimismo, se puede configurar algunos items como Cache Passivation, Eviction, Pool de Conexiones, etc.
Se ofrecen diversos tipos de cache loaders como File System, JDBC (soporta JTA), Hibernate, Cloud cache loader, Remote cache loader y Cassandra cache loader.

Módulos de servidor para Infinispan.


Apartir de la version 4.1 se agrego la posibilidad de usar Infinispan en el modo cliente-servidor, lo cual permite levantar unicamente servidores de Infinispan de manera muy rapida. Esto es por la creacion de distintos modulos de servidor y distintos clientes para estos, permitiendo usar un esquema de acceso como el siguiente (el gráfico lo saque de la página oficial):




Tipos de servidor


Los tipos de servidores se diferencian en el protocolo de comunicación y como manejan las conexiones entrantes.

REST:
  • Distribuído como un archivo WAR, que puede ser deployado en cualquier servlet container permitiendo el acceso a Infinispan vía RESTful interface.
  • Para poder conectarse se puede usar cualquier cliente HTTP.
  • Este módulo es recomendado para entornos donde el puerto HTTP es el único método de acceso permitido entre clientes y servidores.
  • Los clientes de quieran equilibrar la carga o tolerancia a fallas (failover) entre los diferentes REST servers pueden usar culquier HTTP load balancer standard como mod_cluster.

Memcached:
  • Es una implementacion de Memcached text protocol respaldado por Infinispan.
  • Para conectarse se puede usar cualquiera de los Memcached client.
  • A diferencia de los Memcached servers, los Memcached servers basados en Infinispan se los puede poner en cluster y por lo tanto distribuir o replicar informacion usando algoritmos hash. Entonces este modulo es interesante para usuarios que quieran proveer failover de la informacion en Memcaches servers.
  • Algunos clientes soportan load balance y failover pasandoles una lista estatica de direcciones de servidores (perl's Cache::Memcached por ejemplo) pero para agregarle o sacarle algun servidor se tiene que hacer manualmente. 

Hot Rod
  • Hot Rod server es una implementacion de Hot Rod Protocol respaldado por Infinispan que permite a los clientes hacer dynamic load balancing, failover y smart routing.
  • Las opciones de Java Hot Rod client son un poco limitadas debido a su implementacion.
  • Es ideal para clientes que se ejecutan en java, ya que el cliente provee dynamic load balancing y failover. Esto significa que los Hot Rod clients puede detectar dinámicamente cambios en la topología de los Hot Rod servers mientras esten como cluster, entonces cuando nuevos nodos que se unen o se quitan, los clientes actualizan la vista de la topología de los Hot Rod servers. Y cuando los Hot Rod servers son configurados en modo distribución, los clientes pueden detectar donde reside una key en particular y pueden enrutar los pedidos de forma inteligente.
  • Load balancing y failover es dinámicamente proporcionado por el cliente usando la información que le provee el server.

WebSocket

  • Infinispan WebSocket Server permite usar Infinispan sobre un Websocket
  • Este modulo esta específicamente desarrollado para clientes Javascript.
  • Este modulo es particularmente adecuado para desarrolladores que quieran acceder alas instancias de Infinispan desde código Javascript.
  • Los websockets trabajan en el mismo puerto HTTP, se puede usar cualqueir HTTP load balancer.


Modos de clusterización.

Infinispan puede ser configurado como local o cluster. Si es en modo cluster, el cache puede ser configurado para replicar los cambios en todos los nodos, para invalidar cambios en los nodos y finalmente ser usado en modo distribuído (los cambios de estado son replicados en un pequeño grupo de nodos suficientes como para ser tolerante a fallos pero no en muchos nodos para prevenir la escalabilidad). Estas configuraciones suelen ser muy sencillas.

Los distintos modos de clusterización son:

1) Modo Local
  • Permite tener los datos en memoria como JBoss Cache y EHCache. Algunas de las caracteristicas que ofrece:
  • Mantener los datos en memoria para después persistirlos, ejemplo: cache level-2 para Hibernate.
  • Eliminar objetos para evitar quedarse sin memoria.
  • Vencimiento de objetos en cache.
  • Fue pensado para lograr un alto rendimiento en entornos multi-CPU/multi-core.
2) Modo replicación
  • Es un simple modo de clusterización donde cada instancia de cache descubre otras instacias de cache (en distintas JVM) dentro de la red local y formar un cluster. Las entradas que se agregan al cache en cualquiera de las instancias son replicadas a todas las instancias del cluster y pueden ser obtenidas localmente desde cualquier instancia. Este modo permite una manera rápida de compartir estados a través del cluster, pero este modo solo es performante en cluster pequeños (por debajo de los 10 servers), debido a la cantidad de replicaciones que debe hacer.
  • Este modo puede ser sincrónico o asincrónico. El sincrónico bloquea la llamada (ejemplo: put()) hasta que se replica en todos los nodos. En cambio el asincrónico es mas rapido debido a que no hace falta que se replique inmediatamente en todos los nodos, por los tanto no produce bloqueos de ningun tipo. El asincrónico va a replicar en determinados intervalos de tiempo, cuando se llene la cola de elementos o una combinacion de estos.
3) Modo invalidación
  • Este modo no comparte información. Lo que hace es borrar información que puede ser vieja desde caches remotos. Usar este modo solo tiene sentido si se tiene respaldo de la información como una base de datos.
  • Es usado para tener un acceso rapido a datos sin tener que acceder a la base cada vez que se soliciten estos. Se suele usar con cache loaders, puede ser sincrónico o asincrónico.

4) Modo distribuído
  • Este es un modo poderoso que permite a Infinispan escalar linealmente a medida que se agregan mas servers al cluster. La distribucion hace el uso de un algoritmo hash consistente que determina donde deben ser almacenadas las entradas dentro del cluster.
  • El numero de copias que mantiene en el cluster es un equilibrio entre la performance y la durabilidad de la información.

5) Hot Rod Client

Hot Rod es un protocolo binario para la comunicación con el cluster. Este es sencillo de usar, pero posee ventajas y desventajas comparado con el resto de los clientes para los otros modulos.

Ventajas:
  • Sencillo uso a traves de su API.
  • Configuración simple.
  • Es inteligente.
  • Para que funcione solo se debe conocer la ip y puerto de nodo.
  • Maneja el pool de conexiones.
  • Posee estrategias para el balance entre nodos.
  • Detecta la topologia de la red y si esta fue modificada (cuando se agregan o quietan nodos).
  • Detecta automaticamente todos los nodos del cluster solo configurandole con una ip de estos. Conoce la distribución de las keys en los nodos lo cual baja la carga de trabajo de estos.

Desventajas:
  • Solo soporta comunicación TCP.
  • No soporta queries en el cache.
  • No soporta las estadísticas.
Este post lo he adaptado de un informe que he realizado junto con Guillermo Kessler.

miércoles, 15 de junio de 2011

EhCache

EhCache es un cache open source, basado en standards, escalable, robusto, performante y basado en java. Es mantenido por Terracota, quien como un plus provee un servidor adicional para mejorar la performance del cache. Se puede bajar de http://ehcache.org.

Sus características principales son:
  • Rápido y simple de usar.
  • Pequeño (menos de 700 kb) y con pocas dependencias.
  • Escalable: permite, por un lado, escribir a disco y, por otro, trabajar con muchos caches en paralelo.
  • Flexible: permite trabajar con Objects o Serializables y configurarlo mediante xml o programaticamente.
  • Extensible: se pueden adicionar plug-ins, loaders, listeners, JMX y exceptions handlers. Trabaja con varias APIs como JTA o frameworks como Hibernate.
  • Distribuído: posee muchas opciones de replicación de los datos.
  • Cache Server: permite agregarle servidores standalone (o un war, en su defecto).


Como funciona.

Es muy sencillo de utilizar. El API nos provee diversas formas de crear un cache y la más sencilla es simplemente pasando un parámetro String con el nombre del cache a un método (addCache) de la clase CacheManager.


Veremos los métodos de colocación/obtención de datos del cache. Como se observa hay que crear un nuevo objeto Element por cada entrada. Esto mucho no me gusta, pero la realidad es que lo hace de manera muy rápida.



Datos útiles.

Para enviar datos a disco el cache ofrece el método flush(). Para saber el estado general del cache nos ofrece varios métodos que nos dan diversa información. Los más usados son:



¿Que más nos ofrece EhCache?

Se puede configurar de diversas maneras para su mejor performance. Un link interesante para ello se ofrece en la página oficial: http://ehcache.org/documentation/offheap_store.html
También posee un API que nos permite buscar datos en el cache, lo cual puede resultarnos muy útil: http://ehcache.org/documentation/search.html verán que el API es muy parecido al Criteria de Hibernate.

martes, 14 de junio de 2011

JBoss Cache

Es un cache transaccional, clusterizado y basado en una estructura de árbol. Obviamente también puede funcionar en modo “standalone“ y sin clusterizarlo.

Lo podemos bajar de su page oficial: http://www.jboss.org/jbosscache en la sección Downloads. Si leemos la documentación oficial veremos que hay una versión que especial para trabajar con clases POJOs y el cache viene prreparado para trabajar sus relaciones. No vamos a tener en cuenta esta particular versión.

Sus ventajas más importantes son:
  • API simple para trabajar el cache.
  • Es eficiente y “thread-safe”.
  • Posibilidad de replicar a algunos o todos los clusters.
  • Persistencia a disco o remota.
  • Garbage collector inteligente.

Como funciona.

Esta organizado como un árbol, con un único elemento raiz. Cada nodo del árbol que tiene un Map donde guarda objetos que hayan implementado la interface java.io.Serializable.
La forma más sencilla de comenzar a utilizarlo es mediante su interface Cache que se puede obtener mediante un CacheFactory que se basa en un xml u objeto java. Una vez que se tenga acceso al Cache, se puede navegar su estructura para guarda u obtener datos.

Aqui un ejemplo de como he creado un cache:

El ejemplo sigue así: he colocado 2000 objetos del tipo String y luego los he obtenido. Si vemos la salida por consola observamos que se perdió más tiempo en colocarlo que en obtenerlos.

Para colocar y obtener datos he utilizado 2 métodos:


Los nombres de los nodos es arbritario y es recomendable verlo como un grupo lógico de datos. La clase Fully Qualified Name (Fqn) encapsula un patch a una ruta determinada del árbol.
La interface Cache también publica los métodos put/get/remove que reciben un Fqn como parámetro. Esto evita tener que trabajar con nodos:



Tipos de Cache
Se pueden setear diversos tipos de Cache:
  • LOCAL: local, sin cluster.
  • REPL_SYNC: replica de manera sincronizada con los otros cluster. Implica que los cambios son replicados y el cluster que disparó el cambio de datos se bloquea hasta tener el OK del resto.
  • REPL_ASYNC: replica de manera asincrónica. Es decir, que el cluster que dispara el cambio no se bloquea, sique trabajando.
  • INVALIDATION_SYNC: cuando un dato es actualizado en uno de los clusters, no lo replica, solo envía un mensaje al resto diciendo que sus datos son inválidos. Trabaja de manera sincronizada.
  • INVALIDATION_ASYNC: ídem anterior, pero trabaja de manera asincrónica.

En mi ejemplo, no he utilizado clusters por lo tanto lo seteo de manera local:



Cache Listerners

Hay varios tipos de eventos que podemos “escuchar” si fuese necesario. Como son muchos, no voy a nombrar todos aquí. Les recomiendo que vean el siguiente link para ver todas las posibilidades que hay: http://docs.jboss.org/jbosscache/3.2.1.GA/userguide_en/html_single/index.html#api.listener

Los eventos más comunes para escuchar son:
@CacheStarted
@CacheStopped
@NodeCreated
@NodeModified
@NodeRemoved
@CacheBlocked
@CacheUnblocked

Por suerte los nombres son muy descriptivos y no necesitan mayor explicación. Se utiliza de la siguiente manera:



¿Que más nos ofrece JBoss?
Si quieren seguir investigando hay muchos temas adicionales para ver como CacheLoaders, manejo de transacciones, politicas de Eviction, configuración por xml y estadísticas entre los temas mas importantes.

Java Cache

“En informática, una cache o caché (esta última única forma reconocida por la RAE Real Academia Española.) es un conjunto de datos duplicados de otros originales, con la propiedad de que los datos originales son costosos de acceder, normalmente en tiempo, respecto a la copia en el caché.” - Wikkipedia

En el mundo Java existen una gran variedad de productos diseñados para almacenar en caché los objetos que suelen ser accedidos frecuentemente de manera que aumente de forma notable el rendimiento de aplicaciones e-bussines. Eliminando accesos innecesarios a la base de datos, se reduce el tráfico de red e incrementa la escalabilidad de las aplicaciones.

Entre los productos más reconocidos podemos nombrar a JBoss Cache, EhCache y el nuevo producto de JBoss: Infinistpan. En los próximos post voy a dar una introducción de cada uno de ellos y luego los compararé para ver cual es el mejor de todos.