Microservicios y uniones de bases de datos

112

Para las personas que están dividiendo aplicaciones monolíticas en microservicios, ¿cómo están manejando el enigma de dividir la base de datos? Las aplicaciones típicas en las que he trabajado hacen mucha integración de bases de datos por razones de rendimiento y simplicidad.

Si tiene dos tablas que son lógicamente distintas (contextos delimitados si lo desea) pero a menudo realiza un procesamiento agregado en grandes volúmenes de esos datos, entonces en el monolito es más probable que evite la orientación a objetos y en su lugar esté utilizando el estándar de su base de datos ÚNETE a la función para procesar los datos en la base de datos antes de devolver la vista agregada a tu nivel de aplicación.

¿Cómo justifica la división de esos datos en microservicios donde presumiblemente se le pedirá que "unir" los datos a través de una API en lugar de en la base de datos?

Leí el libro de microservicios de Sam Newman y en el capítulo sobre dividir el monolito da un ejemplo de "Rompiendo relaciones de clave externa", donde reconoce que hacer una unión a través de una API será más lento, pero continúa diciendo si su aplicación es lo suficientemente rápida de todos modos, ¿importa que sea más lenta que antes?

¿Esto parece un poco simplista? ¿Cuáles son las experiencias de las personas? ¿Qué técnicas utilizó para que las uniones de API funcionen de manera aceptable?

Martin Bayly
fuente
2
Buena pregunta, estoy experimentando el mismo problema y terminé teniendo una vista materializada y uniéndome a eso. No me gusta, pero supongo que será un desafío con Micro Services. No hay una forma correcta de hacer esto, es solo una elección de diseño. Sé que mucha gente dice que podemos tener una visión materializada, pero las respuestas agregadas se convierten en un problema. Avísame si encontraste algo mejor.
PavanSandeep
Sé que esto es antiguo, pero, ¿es algo que resuelve graphql? También estoy investigando esto para una migración segmentada, y parece que graphql es la forma de hacerlo sin problemas.
themightybun
En algún momento deberías darte cuenta de que ser dogmático no es el camino a seguir. GraphQL es un buen ejemplo de agregación fuera de la fuente de datos y, por lo general, funciona bien.
Christian Ivicevic

Respuestas:

26
  • Cuando el rendimiento o la latencia no importan demasiado (sí, no siempre los necesitamos), está perfectamente bien usar API RESTful simples para consultar los datos adicionales que necesita. Si necesita hacer varias llamadas a diferentes microservicios y devolver un resultado, puede usar el patrón API Gateway .

  • Está perfectamente bien tener redundancia en entornos de persistencia Polyglot . Por ejemplo, puede usar la cola de mensajes para sus microservicios y enviar eventos de "actualización" cada vez que cambie algo. Otros microservicios escucharán los eventos requeridos y guardarán los datos localmente. Entonces, en lugar de realizar consultas, mantiene todos los datos requeridos en el almacenamiento adecuado para un microservicio específico.

  • Además, no se olvide del almacenamiento en caché :) Puede utilizar herramientas como Redis o Memcached para evitar consultar otras bases de datos con demasiada frecuencia.

savia
fuente
25
Todas son buenas sugerencias, pero todavía me resulta difícil de racionalizar. Tal vez sea porque estamos acostumbrados a hacer mucho procesamiento en la base de datos. Nuestra aplicación actual tiene procedimientos almacenados complicados que procesan grandes volúmenes de datos y luego devuelven un pequeño conjunto de resultados. En una arquitectura de microservicios, creo que estas entidades deberían dividirse en diferentes contextos delimitados. Sabemos que el enfoque actual es desagradable, pero es difícil justificar llevar todos los datos al nivel de la aplicación para procesarlos. Quizás ayudaría más desnormalización o pre-computación de vistas agregadas.
Martin Bayly
1
Sí, ya veo. El enfoque de microservicios no es para todos y debe aplicarlo con cuidado. Probablemente pueda comenzar con cambios más pequeños.
sap1ens
Probablemente, los programadores StackExchange hubieran sido un lugar mejor para hacer esta pregunta: programmers.stackexchange.com/questions/279409/… y otras preguntas etiquetadas microservicios programmers.stackexchange.com/questions/tagged/microservices
Martin Bayly
9

Está bien que los servicios tengan copias replicadas de solo lectura de ciertos datos de referencia de otros servicios.

Dado que, al intentar refactorizar una base de datos monolítica en microservicios (en lugar de reescribir), lo haría

  • crear un esquema de base de datos para el servicio
  • crear * vistas ** versionadas en ese esquema para exponer los datos de ese esquema a otros servicios
  • se une a estas vistas de solo lectura

Esto le permitirá modificar de forma independiente los datos / estructuras de la tabla sin interrumpir otras aplicaciones.

En lugar de usar vistas, también podría considerar usar desencadenantes para replicar datos de un esquema a otro.

Esto sería un progreso incremental en la dirección correcta, estableciendo las uniones de sus componentes, y luego se puede pasar a REST.

* las vistas se pueden ampliar. Si se requiere un cambio importante, cree una v2 de la misma vista y elimine la versión anterior cuando ya no sea necesaria. ** o funciones con valores de tabla, o Sprocs.

mcintyre321
fuente
5

CQRS --- Command Query Aggregation Pattern es la respuesta a esto según Chris Richardson. Deje que cada microservicio actualice su propio modelo de datos y genere los eventos que actualizarán la vista materializada con los datos de unión requeridos de microservicios anteriores. Este MV podría ser cualquier NoSql DB o Redis o elasticsearch que esté optimizado para consultas. Esta técnica conduce a una coherencia eventual que definitivamente no es mala y evita las uniones del lado de la aplicación en tiempo real. Espero que esto responda.

Praful
fuente
2

Separaría las soluciones para el área de uso, digamos operativa y de informes.

Para los microservicios que operan para proporcionar datos para formularios únicos que necesitan datos de otros microservicios (este es el caso operativo), creo que usar API joins es el camino a seguir. No buscará grandes cantidades de datos, puede hacer la integración de datos en el servicio.

El otro caso es cuando necesita realizar grandes consultas sobre una gran cantidad de datos para realizar agregaciones, etc. (el caso de informes). Para esta necesidad, pensaría en mantener una base de datos compartida, similar a su esquema original y actualizarla con eventos de sus bases de datos de microservicios. En esta base de datos compartida, podría continuar utilizando sus procedimientos almacenados, lo que le ahorraría esfuerzos y respaldaría las optimizaciones de la base de datos.

Jaro64
fuente
1

En Microservices creas diff. leer modelos, por ejemplo: si tiene dos diff. contexto delimitado y alguien quiere buscar en ambos datos, entonces alguien necesita escuchar eventos de ambos contextos delimitados y crear una vista específica para la aplicación.

En este caso, se necesitará más espacio, pero no se necesitarán uniones ni uniones.

techagrammer
fuente