Microsserviços e armazenamento de dados

26

Estou pensando em mudar uma API REST monolítica para uma arquitetura de microsserviço e estou ficando um pouco confuso sobre o armazenamento de dados. A meu ver, alguns dos benefícios dos microsserviços seriam:

  • Escalonável horizontalmente - posso executar várias cópias redundantes de um microsserviço para lidar com a carga e / ou com o servidor inoperante.
  • Fracamente acoplado - posso alterar implementações internas de microsserviços sem precisar alterar as outras, e posso implantá-las e alterá-las independentemente, etc ...

Meu problema é com armazenamento de dados. A meu ver, existem várias opções:

  1. Um único serviço de banco de dados compartilhado por todos os microsserviços - isso parece eliminar completamente qualquer benefício do acoplamento flexível.
  2. Uma instância de banco de dados instalada localmente em cada microsserviço - não vejo uma maneira de dimensionar horizontalmente isso, então não acho que seria uma opção.
  3. Cada microsserviço possui seu próprio serviço de banco de dados - isso parece o mais promissor, pois preserva os benefícios do acoplamento flexível e do dimensionamento horizontal (usando cópias de banco de dados redundantes e / ou sharding em vários)

Para mim, a terceira opção parece ser a única opção, mas parece incrivelmente pesada para mim, e uma solução muito superengenharia. Se estou entendendo direito, para um aplicativo simples com 4-5 microsserviços, eu precisaria executar 16 a 20 servidores - duas instâncias reais de microsserviço por microsserviço (em caso de falha do servidor e para implantação sem tempo de inatividade) e duas instâncias de serviço de banco de dados por microsserviço (em caso de falha do servidor etc ...).

Francamente, isso parece um pouco ridículo. 16-20 servidores para executar uma API simples, tendo em mente que um projeto realista provavelmente terá mais de 4-5 serviços? Existe algum conceito fundamental que me falta que explique isso?

Algumas coisas que podem ajudar ao responder:

  • Sou o único desenvolvedor deste projeto e será no futuro próximo.
  • Estou usando o Node.js e o MongoDB, mas estaria interessado em respostas independentes de idioma - uma resposta pode até ser que eu esteja usando as tecnologias erradas!
penalosa
fonte
Por que você precisa de outro serviço de banco de dados para cada microsserviço? O trabalho do serviço de banco de dados pode ser adicionado no respectivo Microservice, pois ele já possui conhecimento no domínio do banco de dados. Não é?
Sazzad Hissain Khan

Respostas:

21

Das três opções, a primeira (um único banco de dados compartilhado) e a terceira (um "serviço de banco de dados") são as mais comuns.

O primeiro é chamado de banco de dados de integração . Isso geralmente não é visto como uma boa solução em uma arquitetura de microsserviço. Isso adiciona acoplamento aos seus serviços. Também facilita muito a um serviço simplesmente ignorar os outros serviços e consultar diretamente um banco de dados. Você pode perder qualquer tipo de integridade ou validação de dados fornecida pelo nível do aplicativo não imposto no nível do banco de dados.

Sua terceira ideia é chamada de banco de dados de aplicativos . E você está certo - ele permite impor o acoplamento flexível no nível da API entre os serviços e permite dimensionar mais facilmente os serviços no nível do banco de dados. Também facilita a substituição da tecnologia de banco de dados subjacente por algo apropriado para cada serviço, assim como você pode alterar a tecnologia ou outros detalhes de implementação de cada serviço. Muito flexível.

No entanto, eu proporia uma solução intermediária.

Em vez de levantar um serviço de banco de dados para cada microsserviço, levante um esquema para cada serviço. Se você estiver usando várias tecnologias de banco de dados, pode ser necessário dividir um pouco de maneira diferente, mas a idéia seria minimizar o número de servidores de banco de dados que você está executando, mas facilitar a divisão de um serviço em seu próprio servidor de banco de dados, se e quando se tornar necessário. Contanto que você permita apenas que um banco de dados acesse seu próprio esquema, você terá as vantagens de um banco de dados de aplicativo, mas sem a sobrecarga de servidores de banco de dados existentes para cada aplicativo ou serviço.

No entanto, como desenvolvedor solo, eu desafiaria toda a noção de microsserviços neste momento - Martin Fowler escreve sobre o Monolith First e o Microservice Premium , Simon Brown fala sobre monólitos modulares e DHH fala sobre o Majestic Monolith. Não sei ao certo como o seu monólito está organizado, mas refatore e organize-o. Identifique componentes e faça separações limpas entre eles para extrair peças em um serviço facilmente. O mesmo vale para sua estrutura de banco de dados. Concentre-se em uma arquitetura boa, limpa e baseada em componentes que possa oferecer suporte à refatoração em serviços. Os microsserviços adicionam muita sobrecarga para um único desenvolvedor criar e dar suporte nas operações. No entanto, quando você realmente precisar dimensionar parte do sistema, use seus sistemas de monitoramento e relatório para identificar os gargalos, extrair para um serviço e dimensionar conforme necessário.

Thomas Owens
fonte
1

Cada microsserviço possui seu próprio serviço de banco de dados - isso parece o mais promissor, pois preserva os benefícios do acoplamento flexível e do dimensionamento horizontal (usando cópias de banco de dados redundantes e / ou sharding em vários)

Aceita. A terceira opção é a escolha natural para microsserviços. Se o microsserviço é realmente independente (e não faz parte de um monólito distribuído ), é normal que eles tenham, cada um, um banco de dados.

[...] duas instâncias reais de microsserviço por microsserviço (em caso de falha do servidor e para implantação sem tempo de inatividade) e duas instâncias de serviço de banco de dados por microsserviço (em caso de falha do servidor etc ...).

Você está certo sobre a quantidade de microsserviços em execução se desejar ter um equilíbrio de carga. Se você planeja ter 4 microsserviços, precisa preparar pelo menos 2 instâncias de cada microsserviço (8 no total), como já explicado.

Mas dois bancos de dados por micro serviço? Isso é realmente questionável. Não conheço os detalhes sobre o problema comercial que seus microsserviços atenderão, mas a redundância de um banco de dados é bastante para a maioria dos produtos / projetos. Recomendarei começar com um único banco de dados com um bom backup e minimizar (pelo menos inicialmente) a complexidade da sua infraestrutura.

Francamente, isso parece um pouco ridículo. 16-20 servidores para executar uma API simples, tendo em mente que um projeto realista provavelmente terá mais de 4-5 serviços? Existe algum conceito fundamental que me falta que explique isso?

Para uma API simples, esses números não correspondem. Preste atenção se você não estiver caindo em uma das armadilhas "Microservice First" .

Dherik
fonte
Acrescentarei que, no que diz respeito aos bancos de dados, o local óbvio para iniciar a redundância é realmente no nível do hardware, principalmente com RAID e backups para armazenamento. É certo que você não será capaz de garantir 100% de tempo de atividade, pois as coisas não relacionadas ao armazenamento podem dar errado (diabos, poderia ter apenas uma falha de software), mas essas geralmente não são tão grandes em comparação com a perda de dados. Se você está preocupado com as despesas, definitivamente deseja se concentrar primeiro na integridade dos dados e depois se preocupar com a maximização do tempo de atividade.
27418 Kat
0

Os microsserviços são uma forma de arquitetura orientada a serviços, talvez ao extremo. Seu objetivo geral é reduzir o acoplamento e permitir o desenvolvimento e implantação independentes.

Muito grosseiramente em termos de arquitetura, microsserviços é um termo que se aplica, digamos, a um nível lógico. Os microsserviços são separados logicamente um do outro. Nesta perspectiva, os microsserviços devem possuir e fornecer seu próprio armazenamento, que deve ser dissociado do armazenamento de outros microsserviços. Para microsserviços, essa independência de armazenamento é fundamental para o objetivo de modularidade e acoplamento flexível.

De uma perspectiva arquitetônica, a escala horizontal se aplica em um nível inferior, mais próximo da implementação, digamos, em um nível físico. Nesse nível, estamos implementando um microsserviço e podemos decompor esse microsserviço único, internamente, em um componente sem estado que é horizontalmente escalável e um componente com estado que é compartilhado por todos os componentes sem estado.  Mas não confundamos apenas a parte sem estado com o próprio microsserviço.

Portanto, quando falamos de microsserviços individuais, estamos no nível lógico falando sobre APIs e responsabilidades separadas e ciclos de desenvolvimento / implantação separados. E quando estamos falando sobre dimensionamento horizontal, estamos no nível físico falando sobre a implementação de um (único) microsserviço e sua decomposição em componentes sem estado e sem estado.

Ao implementar vários microsserviços, temos opções para reutilizar a tecnologia de banco de dados para os componentes com estado:

  • banco de dados separado por microsserviço
  • banco de dados compartilhado com:
    • esquema separado / privado por microsserviço
    • tabelas separadas / privadas por microsserviço

Veja mais aqui .

Um único serviço de banco de dados compartilhado por todos os microsserviços - isso parece eliminar completamente qualquer benefício do acoplamento flexível.

Concordo, se você quer dizer compartilhar tabelas de linhas e colunas, isso não seria realmente microsserviços.

Se pudermos desacoplar - em nossos processos de pensamento - a noção lógica de microsserviços da noção mais física de componentes com e sem estado de um microsserviço, talvez seja mais fácil obter o acoplamento flexível oferecido por microsserviços, mantendo a eficiência de um serviço compartilhado. bancos de dados.

Geralmente, há uma quantidade razoável escrita sobre microsserviços e persistência com estado, veja também aqui .

Erik Eidt
fonte
-1

Bem, eu li todas as postagens deste tópico e posso dizer que estou confuso com a pergunta: ele mistura microsserviço (MS) com serviços com serviço de acesso a dados (serviço DB) com bancos de dados e servidores ...

Se o MS é um componente independente (implantável) que resolve uma tarefa mais simples de um estado sem estado, DE QUE banco de dados ele precisa? Se uma tarefa mais complexa a ser resolvida, que exige que mais de uma subtarefa mais simples (EM?) Seja resolvida em conjunto, ainda é uma EM? Em SOA, é chamado serviço de orquestração. Ele implementa "processo" e coordena a chamada do MS, portanto, ele precisa persistir seu estado (todas as orquestrações / organizadores / compositores / etc. São stateful) e precisa de um armazenamento de dados pessoal: ninguém mais pode moderar o estado do orquestrador.

No entanto, não falamos sobre banco de dados, mas sobre o MS / Service do Database Access, e esse é um assunto totalmente diferente. Um MS pode precisar de alguns dados coletados na empresa (não no Aplicativo em que opera) e não pode solicitar outro MS através de sua API / interface para os dados. Este é o cenário mais comum e realista. E outro MS do mesmo aplicativo ou de outro pode precisar desses dados ou até mesmo alterá-los. Sim, eles competem pelos dados, como sempre antes do surgimento da MS.

Por que estamos batendo na 'porta', que é bem conhecida e aberta? Qual é a diferença nesse sentido entre um MS e um objeto persistente regular? Por que precisamos de um banco de dados individual para a MS, se ele (para fins de flexibilidade e composição) envolve o seu Data Access Service (DAS) de qualquer maneira? Não esqueça que o DAS protege o MS com uma tarefa comercial da conscientização sobre conectividade física ao banco de dados. Esse acoplamento flexível e flexibilidade que o MS deve preservar para participar livremente de vários aplicativos sem nenhuma âncora de banco de dados.

Michael Poulin
fonte