REDIS como cache en Liferay DXP
Introducción a REDIS
Acrónimo de REmote DIctionary Server, REDIS es un motor de base de datos en memoria de código abierto, que ofrece tiempos de respuesta inferiores a un milisegundo (tanto en lectura como en escritura), cosa que nos permite pensar que sea una buena solución para dar servicio a aplicaciones en tiempo real.
Como base de datos NoSQL, basa su almacenamiento en tablas de hashes (clave/valor), valores que incluyen una variedad de estructuras de datos como cadenas, listas, conjuntos, conjuntos ordenados, hashmaps (donde clave y valor ahora si son de tipo String), hyperloglogs y mapa de bits.
Aunque REDIS suele guardar su información en memoria RAM, tiene la opción de persistirla a través de configuración. Las posibilidades de persistencia son a través de snapshots guardados en disco, o en un archivo de tipo appendOnly utilizando un sistema Journaling que escribe en el archivo cada modificación que se realice sobre los datos.
Otras de las ventajas de esta base de datos es que sus operaciones son atómicas, la alta disponibilidad y la compatibilidad con clusters.
Casos de uso
Algunos de los principales casos de uso que encontramos de REDIS son: almacenamiento en caché, análisis de datos de streaming, almacen de datos generados en tiempo real para streaming de contenido multimedia, marcadores de videojuegos,…
De todos ellos nos vamos a quedar con el primero, y ahondar brevemente en una implementación que hemos llevado a cabo en Mimacom BCN, en la que hemos sustituido el sistema de caché de un portal Liferay DXP (implemetado con ehCache) por REDIS.
REDIS como cache de DXP
Para llevar a cabo dicho acometido, utilizamos la librería Jedis, que nos proporcionaba la API de comunicación entre REDIS y el portal.
La intención inicial fue modificar toda la caché de Liferay para que en lugar de utilizar la librería de EhCache utilizara la de REDIS (Jedis). Pero nos encontramos que el portal dispone de dos tipos de cache: SingleCache (la utiliza para muy pocos objetos y no se replica en caso de cluster) y MultiCache (la utiliza para la gran mayoría de objetos del portal y se replica). Y en las especificaciones de las clases que utilizaban la primera, al no replicarse, los objetos a almacenar no eran Serializables, requerimiento necesario de Jedis.
Ante esto decidimos mantener la implementación actual de Liferay para SingleCache y solo modificar la Multi, puesto que el motivo de este cambio eran problemas con el proceso de réplica en una arquitectura concreta.
Al no poder sustituir una librería por otra (EhCache por Jedis), con los cambios pertinentes, sino que ambas tenían que convivir, abordamos la sustitución de MultiCache creando una nueva clase RedisVMPool extensión de MultiVMPool (clase punto de entrada a la implementación de MultiCache en el portal) y modificando el proceso de arranque del portal para que en función del valor de la propiedad cache.redis.enabled (portal-ext.properties) se cargue la nueva clase de REDIS o la propia de Liferay.
Los posibles valores que se esperan para esta propiedad son true o false. Y tanto si el valor es negativo, como si la variable no está definida en el fichero de properties, el portal arrancara con la cache original.
Sin embargo, esto era insuficiente, porque así Liferay funcionaba bien en modo “single”, leía y escribía la cache en REDIS, pero los cambios no se apreciaban si había varias instancias a menos se forzara limpieza de cache. El motivo era porque con estos cambios sólo se había sustituido la L0 pero no la L1 de portal.
La L1 en el portal consiste en unos hashes que almacenan en memoria lo que la ehCache devuelve, de manera que si un objeto está almacenado en memoria no hace falta hacer consulta y la respuesta es mucho más rápida.
La solución en caso de estar REDIS activado para el portal es “ignorar” la L1, es decir, no replicar en memoria la cache, sino que cada vez q se requiera un valor se consulte la base de datos. En este caso perdemos rendimiento en algunas consultas del portal, ya que los resultados no se guardan en memoria y siempre hay que acceder remotamente a REDIS, pero la respuesta de este sistema suele ser muy rápida y en todo caso es el valor a pagar por no tener que replicar la información.