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

36

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, isso realmente significa simplesmente ter outro banco de dados dentro da 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, que é um não-não, mas sim a instância do banco de dados.

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

Se usar vários bancos de dados em uma única instância do RDS é uma idéia melhor, ela vai contra a finalidade de ter serviços independentes porque:

  1. O recurso da instância do RDS será compartilhado entre os serviços. O Service A, que pode ter uso pesado do banco de dados em um determinado momento, impacta o Service 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.

por xenon 19.06.2018 / 12:01
fonte

6 respostas

12

Depende realmente dos seus requisitos de escalabilidade e de como / se as instâncias de microsserviço precisam cooperar para fornecer um único resultado. É útil saber quais são os trade-offs:

Mantendo tudo em um banco de dados

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

Manter os bancos de dados separados

  • A resposta completa para uma solicitação pode ser espalhada por instâncias de microsserviço
  • Nesse caso, você aumentou a comunicação e a negociação para resolver a solicitação
  • Manipulando dados quando você solta esse nó de microsserviço (mesmo quando o banco de dados ainda está ativo, você não pode obtê-lo até que um novo com a configuração correta seja mantido)
  • 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 cair, não é um grande problema. Nesses casos, você pode nem precisar 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 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 que suficiente, e gerenciar sua capacidade de resposta de forma independente é a resposta certa.

Existem vários casos intermediários. Por exemplo, você pode ter bancos de dados que são regionalmente específicos, portanto, para cada instância de seu serviço em uma região diferente, você tem um banco de dados separado. Basicamente, os bancos de dados de fragmentação não se dão bem nas regiões, portanto, essa é uma maneira de localizar os dados e controlar a coordenação.

Doutrina e realidade

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

Se o seu microsserviço for pesado em termos de cálculo, faz sentido permitir que o número desses microsserviços seja dimensionado conforme necessário - compartilhar o banco de dados ou até mesmo o código do front end não atrapalha ou atrapalha essa abordagem.

A realidade é que as necessidades específicas do seu projeto precisarão de um conjunto diferente de compromissos para realizar o trabalho em tempo hábil e lidar com a carga do sistema que você está medindo (e um pouco mais). Considere o front-end totalmente isolado, o microsserviço e o trio de camadas de dados como a meta mais importante. Quanto mais demanda do seu sistema, mais próximo a essa meta 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 ficar feliz com isso.

    
por 19.06.2018 / 14:59
fonte
67

Assumindo que você tenha alguns serviços que podem usar o mesmo tipo de sistema e versão de banco de dados, se você usar bancos de dados ou instâncias de banco de dados diferentes, é uma decisão que não deve ser feita 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 serem agnósticos do local onde 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 se adapta bem ao 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 de microsserviço apenas porque você permite que dois deles compartilhem algum recurso - ele viola quando o recurso se torna obrigatório.

    
por 19.06.2018 / 12:22
fonte
12

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 do início e migrar esse serviço de uma instância compartilhada para outra separada. Eu diria que ter instâncias separadas somente por causa desse cenário é um exemplo de YAGNI.

    
por 19.06.2018 / 12:14
fonte
0

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

Se o desempenho do seu microsserviço estiver vinculado ao desempenho do banco de dados : implantar 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 funcionará na mesma velocidade de um único microsserviço

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

Normalmente, seu microserviço obterá dados de um banco de dados, executará alguma lógica e gravará algumas informações no banco de dados. O gargalo de desempenho é a lógica , não o select e / ou insert.

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

    
por 19.06.2018 / 14:13
fonte
0

O objetivo de manter um banco de dados privado em um serviço é o encapsulamento. Seu microsserviço é uma caixa preta que outros serviços no 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 persistir no estado desses objetos. Que algum banco de dados particular faça backup desses objetos de negócios é apenas um detalhe de implementação. Ao manter um banco de dados separado, você impede que outros serviços tenham acesso de backdoor à sua implementação, forçando-os a usar sua interface pública. O objetivo aqui é a arquitetura limpa e a programação disciplinada. Onde exatamente o banco de dados reside é irrelevante neste nível, contanto que seu serviço tenha os detalhes de conexão corretos para que ele possa encontrá-lo.

  • O segundo nível é operacional. Mesmo que seu design seja uma caixa preta perfeita, como você indica, 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 já notaram, se suas necessidades não são muito exigentes e seu orçamento está apertado, este é um argumento pragmático para colocation em uma única máquina. No entanto, como sempre, tradeoffs: esta configuração pode exigir mais babysitting como seu sistema cresce. Se o orçamento permitir, quase sempre prefiro duas pequenas máquinas separadas para executar duas tarefas, em vez de compartilhar uma máquina maior.

por 19.06.2018 / 16:15
fonte
0

Eu acho que pode ser um pouco mais teórico aqui. Uma das ideias motivadoras por trás dos microsserviços são os processos de compartilhamento de mensagens e de nada compartilhado. 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 preferir a essas mensagens). O que se entende por "cada 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 colocado com o microserviço, ou seja, o "banco de dados" deve ser armazenado e executado no mesmo nó lógico do 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, dessa perspectiva, constituiria um estado compartilhado. A maneira "apropriada" de lidar com isso da perspectiva de microsserviços é ter o banco de dados compartilhado mediado por um microsserviço de "banco de dados". Outros microservices que desejassem saber sobre o conteúdo do banco de dados enviariam mensagens para esse "microsserviço do banco de dados". Isso normalmente não elimina a necessidade de estado local (por exemplo, bancos de dados de instâncias de microsserviço) para os microsserviços originais! O que muda é o que esse estado local representa. Em vez de armazenar "User Sally é um admin", ele armazenaria "O microservice do banco de dados dizia 'User Sally é um admin' há cinco minutos". Em outras palavras, além de qualquer estado que ele controla completamente, ele armazenaria suas crenças sobre o estado de outros microsserviços.

O benefício disso é que cada microsserviço é autocontido. Isso faz do microsserviço uma unidade atômica de falha. Você (principalmente) não precisa se preocupar com um microsserviço em algum estado parcialmente funcional. Claro, o problema foi transferido para a rede de microsserviços. Um microsserviço pode não conseguir executar a função desejada devido a ser incapaz de contatar outros microsserviços. O benefício, no entanto, é que o microserviço estará em um estado bem definido e poderá oferecer serviços degradados ou limitados, por ex. trabalhando fora de crenças fora de moda. A desvantagem é que é muito difícil obter um instantâneo consistente do sistema como um todo, e pode haver muita redundância e duplicação (indesejada).

É claro que a sugestão não é inserir 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 traduza 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 ou um banco de dados Sqlite ou uma cópia do Oracle em execução local, se você quiser ou qualquer outro meio de localmente persistentemente armazenar dados. Se o "banco de dados" não for local, então, da perspectiva de microsserviços puros, ele deve ser tratado como um serviço (micro) separado. Para esse fim, nunca faz sentido ter uma instância do RDS como o "banco de dados" para 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 os bancos de dados RDS". Neste ponto, não faz diferença se os dados são armazenados na mesma instância do banco de dados ou não.

Pragmaticamente, uma arquitetura de microsserviços adiciona uma quantidade enorme de complexidade enorme . Essa complexidade é apenas o preço de lidar seriamente com falhas parciais. Para muitos, é um exagero que possivelmente não vale a pena 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 sobre simplicidade e eficiência possam levar a desvios de uma arquitetura pura de microservices. O custo será o acoplamento extra, que introduz suas próprias complexidades, como interações invisíveis entre serviços e restrições à sua liberdade de implantar e escalar como desejar.

    
por 20.06.2018 / 02:03
fonte