Crea, ejecuta y gestiona aplicaciones con Red Hat OpenShift en IBM Cloud. | 22 al 24 de Junio Inscríbete ya

Cómo refactorizar a microservicios, Parte 2: Qué hay que considerar cuando se mueven los datos

Primero, considere qué datos está realmente almacenando

Cuando observa la estructura de su aplicación, elegir la mejor estrategia para gestionar sus datos suele ser cuestión de: «¿Qué está realmente almacenando en su base de datos?

Desde principios de los 90, he ayudado a que las compañías creen, mantengan y, a menudo, torturen marcos de trabajo de mapeo de objeto-relacional (ORM). En algunos casos, los datos que una compañía estaba almacenando, de hecho, no se asignaban bien al modelo de datos relacionales. En esos casos, teníamos que «retorcer» el modelo relacional para que encajase o, con mayor frecuencia, hacer todo lo posible para pasar a través de los programas y forzar el código para que coincidiera con el almacenamiento de datos relacionales.

Ahora que nos encontramos en una era de opciones de persistencia políglotas, podemos volver a analizar algunas de las decisiones anteriores y tomar otras mejores. En particular, veamos cuatro casos en los que el modelo relacionalno era la mejor opción, y luego consideraremos un caso en el que el modelo relacionalera la mejor opción (y refactorizar los datos no hubiera sido la opción adecuada).

Caso 1: Almacenamiento de Blob

Muchas veces he revisado el código de persistencia de sistemas empresariales y lo primero que descubro, para mi sorpresa, es que, de hecho, estaban almacenando en su base de datos relacional representaciones binarias de objetos Java™ serializados . Estos objetos normalmente se almacenan en columnas de «Objetos Binarios Grandes» («Blob») a menudo porque el equipo se rindió debido a la complejidad de mapear sus objetos Java a tablas y columnas relacionales. El almacenamiento Blob, por supuesto, tiene la desventaja de que nunca es consultado en base a la columna, es lento y sensible a los cambios en la estructura de los propios objetos Java: los datos más antiguos pueden ser ilegibles si la estructura del objeto cambia de manera significativa.

Así que si su aplicación (o más probablemente, un subconjunto de su aplicación) está usando almacenamiento Blob en una base de datos relacional, es una muy buena señal de que es más conveniente para usted usar un almacén de valores de clave, como Memcached o Redis.

Por otro lado, si su aplicación está almacenando solamente un objeto Java estructurado (quizá profundamente estructurado, pero no es binario nativo), entonces sería más conveniente para usted usar un almacén de documentos como Cloudant o MongoDB. Además, poniendo un poco de esfuerzo en la manera en la que usted almacena sus documentos (por ejemplo, tanto las bases de datos de Cloudant como de MongoDB son almacenes de documentos JSON, y los analizadores de JSON están ampliamente disponibles y son fáciles de personalizar), puede controlar fácilmente cualquier problema de «cambio de esquema» y de una forma mucho más fácil que con una estrategia de almacén Blob, cuyo mecanismo de almacenamiento es mucho más complejo.

Caso 2: Objetos planos y el patrón del Registro Activo

Hace algunos años, cuando Martin Fowler estaba escribiendo Patrones arquitectónicos de aplicaciones empresariales, nos escribíamos a menudo y tuvimos varias reuniones de revisión interesantes acerca de muchos de los patrones. Un patrón en particular siempre me pareció raro: el patrón del Registro Activo. Era raro porque personalmente nunca lo había encontrado, aunque Martin me aseguraba que era algo común en la comunidad de programación de Microsoft .NET. Pero lo que realmente me llamaba la atención de él, especialmente cuando vi unas cuantas implementaciones Java del mismo usando tecnologías de código abierto como iBatis, era que la mejor manera de usarlo parecía ser con objetos planos.

Si el objeto que usted está mapeando a una base de datos es completa y totalmente plano — sin relaciones con otros objetos (quizá con la limitada excepción de los objetos anidados) — entonces probablemente no esté aprovechando todas las capacidades del modelo relacional. De hecho, es mucho más probable que esté almacenando documentos, como versiones electrónicas de documentos en papel como encuestas de satisfacción del cliente, tiquets de problemas, etc. En ese caso, es probable que una base de datos de documentos como Cloudant o MongoDB se adapte mejor a sus necesidades. Dividir su código en servicios que funcionen en ese tipo de base de datos dará como resultado un código más sencillo y más fácil de mantener.

Caso 3: Datos de referencia

Otro patrón común que he visto en sistemas de mapeo objeto-relacional es la combinación de «datos de referencia en una tabla absorbida por una memoria caché.» Los datos de referencia están compuestos de elementos que no se actualizan a menudo (o nunca), pero se leen continuamente. Un buen ejemplo es la lista de estados de EE. UU. o de las provincias canadienses, pero otros ejemplos incluyen los códigos médicos y las listas de partes estándar. Este tipo de datos a menudo se usa para llenar las listas desplegables de las interfaces de usuarios. El patrón común es empezar a leer la lista de una tabla (normalmente una tabla plana de dos o tres columnas) cada vez que se necesita. Sin embargo, el rendimiento de este patrón es inasequible, así que en cambio, en el arranque, el sistema lo lee desde una memoria interna caché como Ehcache.

Cuando tiene este problema, está rogando ser refactorizado en un mecanismo de cacheo más rápido y simple. Nuevamente, esta es una situación a la que Memcached, el servicio de Cacheo de Datos de IBM Cloud o Redis se adaptarían perfectamente. Si los datos de referencia son independientes del resto de la estructura de su base de datos (a menudo lo son o, como mucho, están muy poco acoplados), entonces resultaría útil separar los datos y sus servicios del resto de su sistema.

Caso 4: La consulta Infernal

En el sistema de un cliente para el que trabajé, estábamos haciendo un modelo financiero complejo que precisaba consultas muy complicadas (del tipo de uniones de seis y siete direcciones) solamente para crear los objetos con los que trabajaba el programa. Las actualizaciones eran incluso más complicadas. Tuvimos que combinar varios niveles diferentes de verificaciones de bloqueo optimistas solamente para descubrir qué había cambiado y si lo que estaba en la base de datos todavía coincidía con la estructura que habíamos creado y manipulado.

En retrospectiva, lo que estábamos haciendo hubiera sido modelado de manera más natural como un gráfico. Las situaciones como ésta (en este caso estábamos modelando porciones de fondos, cada uno compuesto de diferentes tipos de acciones y obligaciones de deuda, cada uno con precios en diferentes divisas y vencimientos en fechas diferentes, con cada valoración dependiendo de reglas diferentes) están casi suplicando por una estructura de datos que les permita hacer fácilmente lo que usted realmente quiere hacer: recorrer el gráfico hacia arriba y hacia abajo y mover partes del gráfico a voluntad.

Este es el tipo de situación en el que Neo4J o Apache Tinkerpop (que está detrás del servicio de base de datos IBM Graph de IBM Cloud) sería una buena estrategia. Si hubiéramos modelado la solución directamente como un gráfico, habríamos evitado una gran cantidad de código Java y SQL complicado y, al mismo tiempo, probablemente habríamos mejorado considerablemente el rendimiento de nuestro tiempo de ejecución.

Caso 5: Su modelo de datos está funcionando

Ahora que hemos acabado los cuatro casos de «disonancia» de datos del modelo relacional, quiero mostrarle un caso donde no querría intentar separar sus datos del principal almacén de datos de la empresa.

Uno de mis clientes tenía el siguiente problema: era una agencia gubernamental que existía para brindar servicios a un solo grupo de interesados, los ciudadanos. Pero en sus sistemas empresariales, los ciudadanos estaban representados de maneras diferentes. Era imposible obtener la respuesta de preguntas simples como «¿La persona que hizo esta pregunta es la misma que rellenó este formulario?» Frustraba al gobierno, a los ciudadanos y al personal de TI que se veía atrapado en el medio. Sabían que tenían que intentar algo diferente.

Cuando comienzo a hablarles a los clientes acerca de microservicios, a menudo me dicen: «No podemos hacer eso. Hemos invertido demasiado en nuestro modelado de datos empresariales.» En cierto sentido, tienen razón: nadie quiere entrar en su modelo de datos empresariales y extraer cosas que están profundamente conectadas con otros conceptos. Es una tarea inútil. Si su modelo de datos funciona y no le está dando problemas, no hay ninguna razón para cambiarlo.

La tendencia hacia la gestión de datos maestros

No todos los modelos de datos están igualmente libres de problemas. De hecho, hay otra tendencia que se está moviendo en una dirección similar. Esta tendencia simultánea no proviene de los desarrolladores, sino más bien de los modeladores de datos y DBA. Es la tendencia hacia la gestión de datos maestros o MDM. En cierto modo, es la misma idea: la noción de que en una empresa no debería haber varias vistas de un concepto importante como un «cliente». Las herramientas MDM le ayudan a combinar todas estas diferentes vistas de los conceptos y, por consiguiente, eliminar la duplicación no necesaria.

La diferencia es que las soluciones MDM están centradas en los datos en vez de en las API. Sin embargo, uno de los resultados comunes de aplicar una solución MDM es crear un conjunto de API centralizado para representar el acceso a esos conceptos comunes a través de la herramienta MDM. No hay ninguna razón por la que no se pueda tratar esas API como los cimientos de una estrategia basada en microservicios. Simplemente sepa que la implementación no se hace en la misma herramienta. Pero al final, la moraleja de la arquitectura de los microservicios es que lo importante es la API y no la implementación.

Finalización

Hemos revisado cuatro casos en los que el «aroma del código» específico lo lleva a creer que, en el fondo, usted tiene un problema de modelado de datos que se resolvería con la refactorización de sus datos basándose en microservicios. Si descubriese que tiene uno o más de estos problemas de codificación en particular, entonces su situación mejoraría si se apartara de su actual almacén de datos empresariales y lo reubicara con un tipo de almacén de datos diferente.

En el próximo y último artículo de esta serie, tomaremos lo que hemos aprendido en estos dos primeros artículos y le mostraremos cómo seguir un procedimiento paso a paso para hacer que sus aplicaciones actuales evolucionen de monolitos a microservicios.

El servicio de caché de datos https://console.ng.bluemix.net/catalog/services/data-cache/ lo ayuda a mejorar el rendimiento y la experiencia del usuario de las aplicaciones web, mediante la recuperación de la información desde cachés en memoria rápidas y administradas, en vez de depender totalmente de las bases de datos más lentas basadas en discos. El servicio de base de datos IBM Graph https://console.ng.bluemix.net/docs/services/graphdb/index.html?pos=2 lo ayuda a crear aplicaciones eficientes que funcionan con un servicio de base de datos gráfica totalmente administrada que se puede acceder a través de una interfaz HTTP API basada en REST.

Kyle Brown