¿Es esta una arquitectura apropiada, o se pueden hacer mejoras?

7

Debido a una combinación de requisitos empresariales / empresariales y las preferencias de nuestro arquitecto, hemos llegado a una arquitectura particular que me parece un poco extraña, pero tengo un conocimiento arquitectónico muy limitado y aún menos conocimiento de la nube, por lo que me encantaría un control de cordura para ver Si hay una mejora que se puede hacer aquí:

Antecedentes: estamos desarrollando un reemplazo para un sistema existente que es una reescritura completa desde cero. Esto requiere que obtengamos datos de una instancia de SAP a través de los servicios web BAPI / SOAP, así como que usemos algunas bases de datos propias para datos que no están en SAP. Actualmente, todos los datos que administraremos existen en bases de datos locales en una aplicación distribuida, o en una base de datos MySQL que deberá migrarse. Tendremos que crear un puñado de aplicaciones web que replican la funcionalidad de la aplicación distribuida existente, así como proporcionar funcionalidad relacionada con el administrador sobre los datos que controlamos.

Requisitos empresariales / empresariales:

  • Cualquier base de datos que controlemos debe implementarse en MS SQL Server

  • Minimice la cantidad de bases de datos creadas

  • La fase 1 nos permitirá implementar nuestras aplicaciones en Azure, pero necesitamos la capacidad de llevar estas aplicaciones a las instalaciones en el futuro

  • Nuestro equipo de operaciones quiere que reduzcamos todo, ya que creen que hará que su gestión del código sea mucho más simple.

  • Minimizar / eliminar la replicación de datos

  • La pila de codificación será .NET Core para microservicios y aplicaciones de administración, pero Angular 5 para la aplicación front-end principal.

A partir de estos requisitos, nuestro arquitecto ideó este diseño: Arquitectura principal

Nuestros front-end se alimentarán de una serie de microservicios (uso ese término a la ligera, ya que son de 'Dominio' y bastante grandes), que se dividirán en Servicios de lectura y Servicios de escritura en cada dominio. Ambos serán escalables y de carga equilibrada a través de Kubernetes. Cada uno también tendrá una copia de solo lectura de su base de datos adjunta dentro de su contenedor, con una única instancia maestra de la base de datos disponible para escrituras que enviará actualizaciones a esas copias de solo lectura.

arquitectura de contenedores Arquitectura de lectura y escritura

(Perdón por las imágenes de baja calidad, las estoy rehaciendo de memoria ya que, naturalmente, no hay documentación real para estas cosas, excepto en la cabeza del arquitecto)

La comunicación de servicio a servicio se realizará a través de una cola de mensajes que cada servicio escuchará y procesará los mensajes relevantes. El uso principal de esto será para la generación de correo electrónico, ya que no hay nada más que hayamos identificado que requiera comunicación de servicio a servicio para obtener información. Cualquier cosa relacionada con la "lógica de negocios" que requeriría la participación de múltiples servicios probablemente fluiría desde los front-end, donde los front-end llamarían a cada servicio individualmente y se ocuparían de la atomicidad.

Desde mi punto de vista, lo que me molesta es las instancias de DB de solo lectura que giran dentro de los contenedores de la ventana acoplable para los servicios. El servicio en sí y la base de datos tendrían demandas drásticamente diferentes en términos de carga, por lo que tendría mucho más sentido si pudiéramos equilibrarlas por separado. Creo que MYSQL tiene una forma de hacerlo con las configuraciones maestro / esclavo, donde los nuevos esclavos pueden activarse cada vez que la carga se eleva. Especialmente mientras tenemos nuestro sistema en la nube y estamos pagando por cada instancia, girar una nueva instancia de todo el servicio cuando solo necesitamos otra instancia de db parece un desperdicio (al igual que lo contrario, girar una nueva copia de db cuando realmente solo necesita una instancia de servicio web). Sin embargo, no conozco las limitaciones de MS SQL Server para esto.

Mi mayor preocupación es la implementación de MS SQL Server. Acoplando las instancias de solo lectura tan estrechamente a los servicios se siente mal. ¿Hay una mejor manera de hacer esto?

NOTA: pregunté esto sobre ingeniería de software y me señalaron aquí. Lo siento si este no es el SE apropiado.

Tampoco hay una etiqueta de MS SQL Server

Marshall Tigerus
fuente
44
Sin duda, poner una base de datos y un servicio web dentro del mismo contenedor no es una buena práctica. Realmente no puedo decir para los servidores MS SQL, pero sí admiten la replicación, hasta qué punto (número de réplicas) no tengo idea.
Tensibai

Respuestas:

2

Mi mayor preocupación es la implementación de MS SQL Server. Acoplando las instancias de solo lectura tan estrechamente a los servicios se siente mal. ¿Hay una mejor manera de hacer esto?

Esencialmente, lo que usted ha diseñado es un sistema de almacenamiento en caché: los contenedores de servicio tienen una copia local de los datos, presumiblemente para que para las lecturas no tengan que hacer un viaje de red adicional.

Como ha señalado, un enfoque más estándar es tener un grupo de réplicas de lectura que todos los contenedores puedan leer. Esto le permite escalarlos por separado de los servidores de aplicaciones, lo cual es bueno, ya que generalmente necesitan cosas diferentes (¿realmente desea asignar grandes cantidades de RAM a cada contenedor de aplicaciones?). Esto agregará llamadas de red para lecturas de bases de datos, pero hasta que se demuestre que es un problema, no complicaría la arquitectura para resolverlo.

Si lo hace convertirse en un problema, una forma mucho más ligero de manejar el problema es ejecutar una caché real a nivel local, como memcache o Redis. Puede ajustar los TTL en objetos individuales para que sean apropiados, y automáticamente dejará los datos solicitados raramente para mantener el servidor de aplicaciones ligero.

Xiong Chiamiov
fuente
¿conoce alguna forma de equilibrar la carga / generar nuevas instancias de las copias de lectura para el servidor ms sql?
Marshall Tigerus
No tengo ninguna experiencia con SQL Server, pero debería poder utilizar los procesos normales. Si su carga es bastante constante, puede crear nuevos esclavos de la forma en que lo haría normalmente; Si necesita escalar automáticamente hacia arriba y hacia abajo, eso depende de su plataforma de alojamiento. Y puede equilibrar las solicitudes de carga entre ellos con un equilibrador de carga de su elección.
Xiong Chiamiov el
1

Podría hablar mucho sobre la arquitectura, pero esta es una comunidad devops, por lo que abordaré su principal preocupación solo sobre la ejecución de la base de datos.

Respuesta corta:

Si tuviera que modificar el diseño para decir "Azure SQL" para cada microservicio, me parecería correcto. Cada microservicio puede tener su propia instancia de base de datos de Azure SQL separada (probablemente ejecutándose en un clúster compartido pero eso es invisible para usted). Para moverlo localmente más adelante, puede decidir si desea crear una configuración "Azure SQL-like" en kubernetes o simplemente ejecutar un clúster tradicional de SQL Server on-prem. El uso de Azure SQL no bloquea su arquitectura en Azure, como explicaré a continuación.

Respuesta larga:

MS SQL Server requiere una gran cantidad de memoria en comparación con las bases de datos de código abierto o los servicios de aplicaciones sin estado. También requiere licencias de software (veremos el costo de optimización a continuación). Por lo tanto, puede darse el caso de que simplemente no sea particularmente rentable ejecutar una instancia con licencia por servicio. Puede licenciar una instancia de SQLServer y ejecutar muchas bases de datos privadas por servicio en ella. Mejor aún, use Azure SQL, la versión administrada de la base de datos como servicio de SQL Server. Eso no los bloquea en Azure, ya que puede pasar a AWS que tiene "Amazon RDS para SQL Server". Cada proveedor serio de la nube ofrecerá un servicio de base de datos administrado profesionalmente para todas las principales bases de datos.

Además, al señalar que ejecuta una base de datos en el mismo pod de Kubernetes, el código del servidor de aplicaciones no le permitirá escalarlos de forma independiente. Además, los servidores de aplicaciones sin estado pueden ejecutarse en pods que no tienen almacenamiento persistente. Luego, los servidores de aplicaciones sin estado pueden morir y reiniciarse a voluntad y moverse trivialmente entre zonas de disponibilidad en la nube. Obviamente, las bases de datos necesitan un almacenamiento persistente que es "propiedad" de pod. Por lo tanto, una base de datos necesita un reclamo de volumen persistente. Si desea que se ejecuten con alta disponibilidad, necesita que se ejecuten como un conjunto con estado. Ejecutar la base de datos en el mismo pod que el servidor de aplicaciones es algo que un desarrollador podría ejecutar localmente, pero no lo recomendaría para SQL Server, ya que se inicia 10 veces más lento que su código. Más bien, en una computadora portátil Mac, ejecute la imagen del acoplador SQL Server exponiendo su puerto.

Se considera una arquitectura muy estándar para cada microservicio que tiene su propia base de datos lógica (pero no necesariamente física), pero se ejecuta como un servicio sin estado con muchas réplicas, para que puedan escalarse de forma independiente. Azure también tiene muy buen soporte para Redis como caché. Por lo tanto, se considera una arquitectura estándar para que cada microservicio tenga su propia base de datos privada lógica, su propio caché de Redis privado y muchos pods escalados independientemente. Si alquila Azure SQL y Azure Redis, no puede elegir cómo ejecutarlo físicamente. ¿Y por qué quieres hacerlo? Deje que los profesionales descubran cómo ejecutar una configuración flexible que tenga un alto rendimiento que pueda "pagar por lo que usa" y concéntrese en escribir su lógica de negocios y no en administrar servicios con estado en la nube que pueda alquilar fácilmente.

He visto desarrolladores que ejecutan MS SQL Server Express localmente en su computadora portátil para depurar y probar la unidad, luego se implementan en Kubernetes en Azure, donde todas las bases de datos de microservicios se ejecutan en Azure SQL. También he visto equipos que se ejecutan contra Azure SQL en producción, pero prueban contra la configuración de SQL Server en máquinas virtuales simples en Azure. ¿Por qué? Porque Azure SQL solo viene con "precios de producción". Esa organización ya tenía SQL Server local y DBA, por lo que era más barato para ellos instalar y ejecutar SQL Server en máquinas virtuales en Azure para alojar las pruebas de entorno. Todos los microservicios tenían sus propias bases de datos privadas. En la prueba, las bases de datos por microservicio se encontraban en una instancia de SQL Server compartida en máquinas virtuales con un clúster de dos nodos para mayor resistencia. En producción, las instancias por microservicios estaban todas en Azure SQL para un alto rendimiento y alta disponibilidad,

simbo1905
fuente
Le recomendaría que lea la documentación oficial de los patrones de Azure. Son muy claros y le darán muchas cosas que puede señalar en sus debates. Por ejemplo, la arquitectura que se le ha dado se basa en CQSR. La documentación de la arquitectura de Azure me pareció muy buena y cubre muchos de los patrones conocidos con código de muestra y cómo implementarlos en Azure. Puede que no estén actualizados con Kubernete en el código de muestra, pero sin duda para la administración de bases de datos y el diseño lógico para CQSR, serán muy útiles.
simbo1905