Mi experiencia con Microstream: Java In-Memory Database

18 abril
Darwin Algarin, developer en DataArt
Mi experiencia con Microstream: Java In-Memory Database
Como muchos saben, en mi tiempo libre me dedico a crear plugins para el IDE Intellij. De hecho, actualmente estoy trabajando en uno nuevo para el proyecto en el que trabajo en DataArt.

Para contextualizarlos un poco: el cliente tiene una API a través de la cual publicamos nuestros servicios a una arquitectura con kubernetes en AWS. Nos olvidamos de configuraciones y demás, solo montamos nuestro código a bitbucket y le damos a desplegar al branch que deseamos. El plugin que estoy creando consiste en no tener que hacer context switching, es decir, poder hacer el deploy desde el IDE sin tener que salir de allí.

Durante todo el proceso de desarrollo he encontrado que quiero guardar cierta información, pero necesito una DB y no puedo pretender que todas las personas que usen mi plugin instalen Postgres o MySQL. Es por eso que investigué otras opciones, como H2 y SQlite, pero todas me llevaban a la conclusión de que debía agregar una capa extra de data y de converters, que no era lo que yo quería.

Un momento de epifanía

Fue entonces que, encontrándome en esta encrucijada y buscando en Internet, encontré microstream.

microstream

Como su documentación oficial lo define:


High-Performance Java-Native-Persistence

Store and load any Java Object Graph or Subgraphs partially, Relieved of Heavy-weight JPA. Microsecond Response Time. Ultra-High Throughput. Minimum of Latencies. Create Ultra-Fast In-Memory Database Applications & Microservices.


Es decir: una librería de persistencia, nativa en Java y con alta performance, mucho más rápida que una DB. ¿Y cómo logra esto?

Normalmente, cuando tenemos conexión a una DB, debemos crear mappers para convertir nuestras estructuras de datos o nuestros tipos de datos en el modelo de base de datos, y esta conversión toma tiempo de CPU. En cambio, Microstream serializa y deserializa los objetos Java, haciendo posible que no tengamos que hacer ninguna conversión ni adaptar nuestras clases.

¿Cómo lo uso?

1. Agregar dependencia

Java code example

2. Crear una clase root

Java code example

Para quien no lo sabe, root es una clase como cualquier otra (de hecho, puede tener cualquier nombre… pero yo la quise llamar así, XD) pero con la única característica de que va a ser en donde guardamos nuestra colección de datos como la necesitemos. Puede ser, por ejemplo, una lista de personas que tiene a su vez una lista de comentarios y que además tiene la TreeMap de las publicaciones hechas por esa persona.

3. Inicializar la BD

Java code example

Para inicializar nuestra base de datos, crearemos un objeto root por defecto y al método start de la clase EmbeddedStorage le pasaremos como parámetros nuestro objeto root y el path donde queremos que se guarde nuestra DB.

4. Guardar y modificar la información

Java code example

Para modificar información en nuestra base de datos, solo necesitamos modificar los objetos como normalmente lo haríamos en Java o Kotlin y llamar al metodo storeRoot().

5. Ejecutar la prueba

Java code example

He creado una pequeña prueba que lo que hace es modificar el mensaje y luego tomar el root en una nueva variable, para demostrar que el dato guardado sí había cambiado.

Si hubiera tomado como referencia la variable root iniciada al principio, podrían pensar que -como era la misma referencia- por eso me funcionó.

Java code example

Conclusiones

Para quienes se estén preguntando cómo terminó el plugin, bien… Continúa en desarrollo y esta librería era la solución a lo que necesitaba.

Microstream aprovecha los streams de Java y que toda la información la tiene en memoria, y por eso son tan rápidas las consultas. En su página principal tienen una comparativa de lo que sería SQL ejecutado con JPA vs Microstream, y la diferencia es abrumadora. Como dato extra, esta librería viene integrada por defecto con Helidon, un framework nuevo para la creación de microservicios y con soporte a Graalvm.