No microsserviço, é um único banco de dados ou uma instância de banco de dados única para cada serviço?


51

Entendo que cada serviço em uma arquitetura de microsserviço deve ter seu próprio banco de dados. No entanto, por ter seu próprio banco de dados, na verdade significa simplesmente ter outro banco de dados na mesma instância de banco de dados ou literalmente ter outra instância de banco de dados?

Por isso, não quero dizer compartilhamento de bancos de dados, o que é um não-não, mas a instância do banco de dados.

Por exemplo, se eu estivesse usando a AWS e tivesse 3 serviços, crio 3 bancos de dados para cada serviço em uma única instância do RDS ou crio 3 instâncias do RDS, cada uma contendo um banco de dados usado independentemente por cada um dos 3 serviços?

Se o uso de vários bancos de dados em uma única instância do RDS for uma idéia melhor, isso anulará a finalidade de ter serviços independentes, pois:

  1. O recurso da instância do RDS será compartilhado entre os serviços. O Serviço A, que pode ter um uso intenso do banco de dados em um determinado momento, afetará o Serviço B, que usa um banco de dados diferente, mas na mesma instância do RDS?

  2. Todos os serviços dependerão da versão do banco de dados nessa instância do RDS.


8
É o que melhor atende às suas necessidades específicas.
Robert Harvey

11
Não tenho certeza se me chamaria de especialista em 'microsserviços', mas você poderia ter qualquer tipo de configuração e dbs. Você pode ter um banco de dados lido por um serviço e gravado por outro. Ou, como alternativa, você poderia ter apenas 1 db (ou menos tecnicamente) para todo o sistema.
Mark Rogers

Aqui está uma boa leitura sobre o assunto: plainoldobjects.com 02/09/2015
RandomUs1r

Leia sobre 'Princípio da responsabilidade única'. Você já pensou em implementar um 'microsserviço de banco de dados' usado por outros microsserviços?
ChuckCottrill

Respostas:


21

Realmente depende de seus requisitos de escalabilidade e de como / se suas instâncias de microsserviço precisam cooperar para fornecer um único resultado. Ajuda a saber quais são as compensações:

Mantendo tudo em um banco de dados

  • Configuração mais fácil
  • Nenhuma coordenação ou comunicação com outras instâncias do seu serviço é necessária
  • Mais fácil de descobrir seu conjunto de dados completo
  • Desempenho do sistema limitado pelo desempenho do banco de dados

Mantendo os Bancos de Dados Separados

  • A resposta completa de uma solicitação pode estar espalhada por instâncias de microsserviço
  • Nesse caso, você aumentou a comunicação e a negociação para resolver a solicitação
  • Manipulação de dados quando você solta esse nó de microsserviço (mesmo quando o banco de dados ainda está ativo, você não pode acessá-lo até que um novo com a configuração correta seja recuperado)
  • Maior complexidade de configuração

Qual é o problema que você está resolvendo?

Em alguns casos, você está preocupado apenas com dados efêmeros. Se o banco de dados ficar inoperante, não é um grande problema. Nesses casos, talvez você nem precise de um banco de dados para começar. Basta manter tudo na memória e tornar as coisas incrivelmente rápidas. Esta é a solução mais fácil de se trabalhar.

Em outros casos, você precisa da integridade dos dados, mas seu banco de dados é capaz de expandir sua capacidade com base no número de nós que possui. Nesse caso, um único banco de dados provavelmente é mais do que suficiente e gerenciar a capacidade de resposta de forma independente é a resposta certa.

Há vários casos no meio. Por exemplo, você pode ter bancos de dados específicos regionalmente, portanto, para cada instância do seu serviço em uma região diferente, você tem um banco de dados separado. Normalmente, os bancos de dados de sharding não funcionam bem em todas as regiões; portanto, essa é uma maneira de localizar um pouco os dados e controlar a coordenação.

Doutrina e Realidade

Eu li vários artigos sobre microsserviços e como eles devem ser modulares. As recomendações vão desde manter o front-end, microsserviço e camada de dados como uma unidade inteira, até o compartilhamento de banco de dados e / ou código de front-end para todas as instâncias. Geralmente, mais isolamento fornece a maior escalabilidade, mas isso implica o custo de maior complexidade.

Se o seu microsserviço é pesado em cálculos, faz sentido permitir a escalabilidade do número desses microsserviços, conforme necessário - compartilhar o banco de dados ou mesmo o código do front-end não prejudica ou dificulta essa abordagem.

A realidade é que as necessidades específicas do seu projeto precisarão de um conjunto diferente de compromissos para concluir o trabalho em tempo hábil e lidar com a carga do sistema que você está medindo (além de um pouco mais). Considere o trio totalmente isolado de front-end, microsserviço e camada de dados como o objetivo principal. Quanto mais demanda em seu sistema, mais próximo desse objetivo você provavelmente precisará estar. Nós não somos todos [insert name of highly successful web entity here], e eles não começaram onde estão agora. Às vezes, você só precisa começar com uma situação menos que perfeita e ser feliz com isso.


72

Supondo que você tenha alguns serviços que podem usar o mesmo tipo de sistema e versão de banco de dados, se você usar diferentes instâncias de banco de dados ou db, é uma decisão que você não precisará tomar em tempo de design. Em vez disso, você deve poder tomar a decisão no momento da implantação, algo que você pode simplesmente configurar. Projete seus serviços para que não sejam independentes do local em que os bancos de dados de outros serviços estão hospedados.

Durante a operação, você pode começar com uma instância e, se o sistema funcionar bem, deixe assim. No entanto, se você perceber que isso não é adequado para o seu sistema, porque bancos de dados diferentes em uma instância compartilham muitos recursos, você sempre tem a opção de usar instâncias diferentes, se isso ajudar.

Portanto, um serviço não viola a arquitetura do microsserviço apenas porque você permite que dois compartilhem algum recurso - ele é violado quando o compartilhamento do recurso se torna obrigatório.


Isso soa como uma otimização prematura. E se os recursos consumidos nunca merecerem instâncias extras? Então você desperdiçou tempo construindo na flexibilidade
reggaeguitar

5
@ reggaeguitar: os custos para isso normalmente devem ser desprezíveis - de fato, para uma arquitetura de microsserviço, pode ser mais difícil tentar centralizar a configuração do banco de dados entre serviços diferentes do que manter a localização do banco de dados para cada serviço configurável individualmente. Além disso, todo o objetivo de uma arquitetura de microsserviço é alta escalabilidade; se não for necessário, não se deve tomar uma decisão para microsserviços em primeiro lugar.
Doc Brown

11
@DocBrown Isso faz sentido, obrigado pela resposta!
reggaeguitar

13

Não importa.

O único cenário em que teoricamente poderia ser importante é se um serviço precisa migrar para versões diferentes do banco de dados. Mas, mesmo assim, não há diferença real entre ter instâncias separadas desde o início e migrar esse serviço de uma instância compartilhada para outra. Na verdade, eu diria que ter instâncias separadas apenas por causa desse cenário é um exemplo de YAGNI.


11
Supondo que, se um serviço em particular tiver um uso pesado em uma única instância do RDS, ele acabará consumindo os recursos dessa instância e afetará os outros serviços usando a mesma instância do RDS?
xenon

11
@xenon: sim, mas essa é uma razão para pensar em melhorar o desempenho do RDS por meio de ajuste, melhor hardware ou cluster, não em mudar a arquitetura do sistema - se esse serviço estiver deixando capacidade para os outros serviços, em breve ficará sem capacidade por si só. Embora eu ache que você possa ter requisitos especiais de que um serviço sobrecarregado não deve afetar os outros. De fato, alguns RDS ainda podem permitir isso em uma única instância, definindo limites de recursos com base no usuário.
Michael Borgwardt

o cenário em que importa é quando a instância de microsserviço tiver seu próprio estado. Em seguida, ele deve ser implantado com a sua própria instância db, que também pode ser um gargalo de desempenho
Ewan

3

Uma instância do RDS é uma única caixa. Se você tiver vários bancos de dados em uma única instância, eles compartilharão a CPU / Memória, etc.

Se o desempenho do microsserviço estiver vinculado ao desempenho do banco de dados : implante várias cópias do microsserviço, cada uma usando um banco de dados diferente, mas com cada banco de dados na mesma instância do RDS. É inútil * (exceto para failover). Seu cluster de microsserviço será executado na mesma velocidade que um único microsserviço

No entanto , eu diria que um microsserviço vinculado ao desempenho do banco de dados é incomum.

Normalmente, seu microsserviço obtém dados de um banco de dados, executa alguma lógica e grava algumas informações de volta ao banco de dados. O gargalo de desempenho é a lógica , não a seleção e / ou inserção.

Nesse caso, você pode simplesmente compartilhar o mesmo banco de dados em todas as suas instâncias de microsserviço


Eu tenho que questionar sua afirmação de que a lógica é o gargalo, não o banco de dados. Na minha experiência, o local mais provável para encontrar melhorias de desempenho é com o banco de dados.
precisa

hmm sim, mas certamente essas melhorias de desempenho são alcançadas movendo a lógica para fora do banco de dados e para o serviço. Depois de ter feito isso, então a lógica é o gargalo
Ewan

11
Normalmente não. Essas melhorias vêm do ajuste de índices e consultas.
precisa

bem, isso se encaixaria no caso incomum da minha experiência. Não que normalmente não haja espaço para essas melhorias, mas depois de remover qualquer coisa muito ruim, o banco de dados ainda é o fator limitante.
Ewan

1

O objetivo de manter um banco de dados privado para um serviço é o encapsulamento. Seu microsserviço é uma caixa preta que outros serviços do sistema usarão por meio de uma interface pública.

Existem dois planos nos quais esse encapsulamento opera:

  • O primeiro é lógico, no nível do aplicativo. Seu serviço possui alguns objetos de negócios em seu sistema e precisa manter o estado sobre esses objetos. O fato de algum banco de dados específico apoiar esses objetos de negócios é apenas um detalhe de implementação. Ao manter um banco de dados separado, você evita que outros serviços tenham acesso backdoor à sua implementação, forçando-os a usar sua interface pública. O objetivo aqui é arquitetura limpa e programação disciplinada. Onde exatamente o banco de dados mora é irrelevante nesse nível, desde que seu serviço tenha os detalhes de conexão corretos para que ele possa encontrá-lo.

  • O segundo nível está operacional. Mesmo que seu design seja uma caixa preta perfeita, como você ressalta, diferentes trabalhos colocados em uma única máquina podem competir por recursos. Esse é um bom motivo para colocar bancos de dados lógicos separados em máquinas separadas. Como outras respostas observaram, se suas necessidades não são muito exigentes e seu orçamento é apertado, esse é um argumento pragmático para a colocação em uma única máquina. No entanto, como sempre, trocas: essa configuração pode exigir mais serviços de babá à medida que o sistema cresce. Se o orçamento permitir, eu quase sempre prefiro duas máquinas pequenas separadas para executar duas tarefas do que compartilhar uma máquina maior.


1

Eu acho que pode ajudar a ser um pouco mais teórico aqui. Uma das idéias motivadoras por trás dos microsserviços é o processo de compartilhamento de mensagens e nada. Um microsserviço é como um ator no modelo de ator. Isso significa que cada processo mantém seu próprio estado local e a única maneira de um processo acessar o estado de outro é enviando mensagens (e mesmo assim o outro processo pode responder da maneira que desejar para essas mensagens). O que se entende por "todo microsserviço tem seu próprio banco de dados" é realmente que o estado de um processo (ou seja, microsserviço) é local e privado . Em grande medida, isso sugere que o "banco de dados" deve ser colocadocom o microsserviço, ou seja, o "banco de dados" deve ser armazenado e executado no mesmo nó lógico que o microsserviço. Diferentes "instâncias" do microsserviço são processos separados e, portanto, cada um deve ter seu próprio "banco de dados".

Um banco de dados global ou um banco de dados compartilhado entre microsserviços ou mesmo instâncias de um microsserviço, nessa perspectiva, constituiria um estado compartilhado. A maneira "apropriada" de lidar com isso da perspectiva dos microsserviços é ter o banco de dados compartilhado mediado por um microsserviço "banco de dados". Outros microsserviços que desejassem saber sobre o conteúdo do banco de dados enviariam mensagens para esse "microsserviço de banco de dados". Isso normalmente não elimina a necessidade de estado local (por exemplo, "bancos de dados" por instância de microsserviço)) para os microsserviços originais! O que muda é o que esse estado local representa. Em vez de armazenar "O usuário Sally é um administrador", ele armazenaria "O microsserviço do banco de dados dizia 'O usuário Sally é um administrador' cinco minutos atrás". Em outras palavras, sobre o estado de outros microsserviços.

O benefício disso é que cada microsserviço é independente. Isso torna um microsserviço uma unidade atômica de falha. Você (principalmente) não precisa se preocupar com um microsserviço em algum estado parcialmente funcional. Obviamente, o problema foi movido para a rede de microsserviços. Um microsserviço pode falhar ao conseguir executar a função desejada devido à impossibilidade de entrar em contato com outros microsserviços. O benefício, porém, é que o microsserviço estará em um estado bem definido e poderá oferecer serviços degradados ou limitados, por exemplo, trabalhando com crenças desatualizadas. A desvantagem é que é muito difícil obter um instantâneo consistente do sistema como um todo e pode haver bastante redundância e duplicação (indesejadas).

Obviamente, a sugestão não é colar uma instância do Oracle em todos os contêineres do Docker. Primeiro, nem todo microsserviço precisa de um "banco de dados". Alguns processos não precisam de nenhum estado persistente para funcionar corretamente. Por exemplo, um microsserviço que traduz entre dois protocolos não precisa necessariamente de nenhum estado persistente. Para quando o estado persistente é necessário, a palavra "banco de dados" é apenas uma palavra para "estado persistente". Pode ser um arquivo com JSON nele ou um banco de dados SQLite ou uma cópia em execução local do Oracle se você quer ou qualquer outro meio de localmentepersistentemente armazenando dados. Se o "banco de dados" não for local, de uma perspectiva pura de microsserviços, ele deve ser tratado como um (micro) serviço separado. Para esse fim, nunca faz sentido que uma instância do RDS seja o "banco de dados" de um microsserviço. Novamente, a perspectiva não é "um monte de microsserviços com seus próprios bancos de dados RDS", mas "um monte de microsserviços que se comunicam com bancos de dados RDS". Neste ponto, não faz diferença se os dados são armazenados na mesma instância de banco de dados ou não.

Pragmaticamente, uma arquitetura de microsserviços adiciona uma enorme quantidade de complexidade. Essa complexidade é apenas o preço de lidar seriamente com falhas parciais. Para muitos, é um exagero que possivelmente não vale os benefícios. Você deve se sentir à vontade para arquitetar seu sistema da maneira que parecer mais benéfica. Há uma boa chance de que preocupações com simplicidade e eficiência possam levar a desvios de uma arquitetura pura de microsserviços. O custo será um acoplamento extra, que apresenta suas próprias complexidades, como interações invisíveis entre serviços e restrições à sua liberdade de implantar e escalar conforme desejar.


"por não poder entrar em contato com outros microsserviços." - Eu pensei que os microsserviços nunca deveriam entrar em contato com outros microsserviços?
Marc
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.