Essa é uma arquitetura apropriada ou podem ser feitas melhorias?

7

Devido a uma combinação de requisitos de negócios / empresa e as preferências de nosso arquiteto, chegamos a uma arquitetura específica que me parece um pouco complicada, mas eu tenho um conhecimento de arquitetura muito limitado e ainda menos conhecimento em nuvem, portanto, gostaria de uma verificação de sanidade para ver se houver melhorias que possam ser feitas aqui:

Antecedentes: estamos desenvolvendo uma substituição para um sistema existente que é uma reescrita completa desde o início. Isso exige que obtenhamos dados de uma instância do SAP por meio dos serviços da Web BAPI / SOAP, além de usarmos alguns bancos de dados próprios para dados que não estão no SAP. Atualmente, todos os dados que gerenciaremos existem em bancos de dados locais em um aplicativo distribuído ou em um banco de dados MySQL que precisará ser migrado. Precisamos criar um punhado de aplicativos da Web que replicam a funcionalidade do aplicativo distribuído existente, além de fornecer funcionalidades relacionadas a administração sobre os dados que controlamos.

Requisitos de Negócios / Empresa:

  • Quaisquer bancos de dados que controlamos devem ser implementados no MS SQL Server

  • Minimize o número de bancos de dados criados

  • A Fase 1 nos permitirá implantar nossos aplicativos no Azure, mas precisamos da capacidade de colocar esses aplicativos no local no futuro

  • Nossa equipe de operações deseja que reduzamos o tamanho de tudo que acham que isso facilitará muito o gerenciamento do código.

  • Minimizar / eliminar a replicação de dados

  • A pilha de codificação será o .NET Core para microsserviços e aplicativos de administração, mas o Angular 5 para o aplicativo front-end principal.

A partir desses requisitos, nosso arquiteto criou este design: Arquitetura principal

Nossos front-ends serão alimentados por uma série de microsserviços (eu uso esse termo levemente, pois são de nível 'Domínio' e bastante grandes), que serão divididos em Serviços de Leitura e Serviços de Gravação em cada domínio. Ambos serão escalonáveis ​​e com balanceamento de carga no Kubernetes. Cada um também terá uma cópia somente leitura do banco de dados anexada a eles em seu contêiner, com uma única instância mestre do db disponível para gravações que enviará atualizações para essas cópias somente leitura.

arquitetura de contêiner Arquitetura de leitura e gravação

(Desculpe pelas imagens de baixa qualidade, estou refazendo-as de memória, pois, naturalmente, não há documentação real para essas coisas, exceto na cabeça do arquiteto)

A comunicação serviço a serviço ocorrerá através de uma fila de mensagens que cada serviço ouvirá e processará as mensagens relevantes. O principal uso disso será na geração de e-mails, pois ainda não identificamos mais nada que exija serviço a serviço de comunicação de informações ainda. Qualquer coisa relacionada à "lógica de negócios" que exigiria a participação de vários serviços provavelmente fluiria dos front-ends, onde os front-ends chamariam cada serviço individualmente e lidariam com a atomicidade.

Na minha perspectiva, o que me atrapalha de maneira incorreta são as instâncias de banco de dados somente leitura girando dentro dos contêineres do docker para os serviços. O serviço em si e o banco de dados teriam demandas drasticamente diferentes em termos de carga, portanto, faria muito mais sentido se pudéssemos equilibrar a carga separadamente. Eu acredito que o MYSQL tem uma maneira de fazer isso com configurações de mestre / escravo, onde novos escravos podem ser ativados sempre que a carga fica alta. Especialmente enquanto temos nosso sistema na nuvem e pagamos por cada instância, exibir uma nova instância de todo o serviço quando precisamos apenas de outra instância de banco de dados parece um desperdício (assim como o oposto, gerar uma nova cópia de banco de dados quando realmente apenas precisa de uma instância de serviço da web). No entanto, não conheço as limitações do MS SQL Server para isso.

Minha maior preocupação é com a implementação do MS SQL Server. Acoplar as instâncias somente leitura com tanta firmeza aos serviços parece errado. Existe uma maneira melhor de fazer isso?

NOTA: Perguntei isso sobre engenharia de software e eles me indicaram aqui. Desculpe se este não é o SE apropriado.

Também não há tag do MS SQL Server

Marshall Tigerus
fonte
4
Certamente, colocar um banco de dados e um serviço da web no mesmo contêiner não é uma boa prática. Eu realmente não posso dizer para servidores MS SQL, mas eles oferecem suporte à replicação, até que ponto (número de réplicas) eu não tenho idéia.
Tensibai

Respostas:

2

Minha maior preocupação é com a implementação do MS SQL Server. Acoplar as instâncias somente leitura com tanta firmeza aos serviços parece errado. Existe uma maneira melhor de fazer isso?

Essencialmente, o que você projetou é um sistema de armazenamento em cache - os contêineres de serviço possuem uma cópia local dos dados, presumivelmente, para que, para leituras, eles não precisem fazer uma viagem extra à rede.

Como você apontou, uma abordagem mais padrão é ter um cluster de réplicas de leitura das quais todos os contêineres possam ler. Isso permite escalá-los separadamente dos servidores de aplicativos, o que é bom, porque eles geralmente precisam de coisas diferentes (você realmente deseja alocar grandes quantidades de RAM para cada contêiner de aplicativos?). Isso adicionará chamadas de rede para leituras do banco de dados, mas até que isso seja um problema, não complicaria a arquitetura para resolvê-lo.

Se isso se tornar um problema, uma maneira muito mais leve de lidar com o problema é executar um cache real localmente, como memcache ou redis. Você pode ajustar os TTLs em objetos individuais para que sejam apropriados, e eles descartam automaticamente dados raramente solicitados para manter o servidor de aplicativos leve.

Xiong Chiamiov
fonte
você conhece uma maneira de balancear / ativar novas instâncias das cópias lidas para o servidor ms sql?
Marshall Tigerus
Não tenho nenhuma experiência com o SQL Server, mas você deve poder usar os processos normais. Se sua carga for bastante constante, você poderá criar novos escravos da maneira que faria normalmente; se você precisar escalar automaticamente para cima e para baixo, isso depende da sua plataforma de hospedagem. E você pode solicitar solicitações de balanceamento de carga entre elas com um balanceador de carga de sua escolha.
Xiong Chiamiov
1

Eu poderia falar muito sobre a arquitetura, mas essa é uma comunidade de devops, então abordarei sua principal preocupação em executar apenas o banco de dados.

Resposta curta:

Se você modificasse o design para dizer "SQL do Azure" para cada microsserviço, pareceria bom para mim. Cada microsserviço pode ter sua própria instância de banco de dados SQL do Azure separada (provavelmente em execução em um cluster compartilhado, mas que é invisível para você). Para movê-lo no local mais tarde, você pode decidir se deseja criar uma instalação "semelhante ao SQL do Azure" nos kubernetes ou simplesmente executar um cluster tradicional do SQL Server no local. O uso do Azure SQL não bloqueia sua arquitetura no Azure, como discutirei abaixo.

Resposta longa:

O MS SQL Server requer uma quantidade enorme de memória em comparação com bancos de dados de código-fonte aberto ou serviços de aplicativos sem estado. Também requer licenças de software (veremos abaixo os custos de otimização). Portanto, pode ser que simplesmente não seja particularmente econômico executar uma instância licenciada por serviço. Você pode licenciar uma instância do SQLServer e executar muitos bancos de dados privados por serviço nela. Melhor ainda, use o Azure SQL, a versão gerenciada do banco de dados como serviço do SQL Server. Isso não os bloqueia no Azure, pois você pode mudar para a AWS, que possui o "Amazon RDS for SQL Server". Todo provedor de nuvem sério oferecerá um serviço de banco de dados gerenciado profissionalmente para todos os principais bancos de dados.

Além disso, ao apontar a execução de um banco de dados no mesmo pod do kubernetes que o código do servidor de aplicativos, não será possível dimensioná-los independentemente. Além disso, os servidores de aplicativos sem estado podem ser executados em pods que não possuem armazenamento persistente. Os servidores de aplicativos sem estado podem morrer e ser reiniciados à vontade e movidos entre as zonas de disponibilidade da nuvem trivialmente. Obviamente, os bancos de dados precisam de armazenamento persistente "pertencente" ao pod. Portanto, um banco de dados precisa de uma reivindicação de volume persistente. Se você deseja que eles sejam executados com alta disponibilidade, é necessário que eles sejam executados como um conjunto com estado. A execução do banco de dados no mesmo pod do servidor de aplicativos é algo que um desenvolvedor pode executar localmente, mas eu não o recomendaria para o SQL Server, pois ele é iniciado 10 vezes mais lento que o seu código. Em vez disso, em um laptop mac, execute a imagem da janela de encaixe do SQL Server expondo sua porta.

É considerada uma arquitetura muito padrão para cada microsserviço que possui seu próprio banco de dados lógico (mas não necessariamente físico), mas para ser executado como um serviço sem estado com muitas réplicas, para que possam ser dimensionadas independentemente. Além disso, o Azure tem muito bom suporte para Redis como cache. Portanto, é considerada uma arquitetura padrão para cada microsserviço ter seu próprio banco de dados privado lógico, seu próprio cache Redis privado e muitos pods escalados independentemente. Se você estiver alugando o Azure SQL e o Azure Redis, não poderá escolher como eles o executarão fisicamente. e por que você iria querer? Deixe os profissionais descobrirem como executar uma configuração resiliente com alto desempenho que você pode "pagar pelo que usa" e se concentrem em escrever sua lógica de negócios, não no gerenciamento de serviços com estado na nuvem que você pode alugar com facilidade.

Eu vi desenvolvedores executando o MS SQL Server Express localmente em seu laptop para depurar e testar a unidade e, em seguida, implantar no Kubernetes no Azure, onde os bancos de dados de microsserviços estão em execução no SQL do Azure. Também vi equipes executadas no SQL SQL do Azure em produção, mas testadas na instalação do SQL Server em VMs simples no Azure. Por quê? Porque o Azure SQL vem apenas com "preços de produção". Essa organização já possuía o SQL Server no local e DBAs, por isso era mais barato instalar e executar o SQL Server em VMs no Azure para hospedar os envs de teste. Todos os microsserviços tinham seus próprios bancos de dados privados. Em teste aqueles por banco de dados de microsserviço em uma instância compartilhada do SQL Server em VMs com um cluster de dois nós para resiliência. Na produção, as instâncias por microsserviços estavam todas no SQL do Azure para alto desempenho e alta disponibilidade,

simbo1905
fonte
Eu recomendo que você leia a documentação oficial de padrões do Azure. Eles são muito claros e fornecerão muitas coisas para as quais você pode apontar em suas discussões. Por exemplo, a arquitetura que você recebeu é baseada no CQSR. Achei a documentação da arquitetura do Azure muito boa e abrange muitos padrões conhecidos com código de exemplo e como implantá-los no Azure. Eles podem não estar atualizados com o Kubernete no código de exemplo, mas certamente para o gerenciamento de banco de dados de recomendação e o layout lógico para CQSR, eles serão muito úteis.
precisa saber é o seguinte