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:
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?
Todos os serviços dependerão da versão do banco de dados nessa instância do RDS.
Respostas:
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
Mantendo os Bancos de Dados Separados
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.fonte
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.
fonte
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.
fonte
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
fonte
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.
fonte
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.
fonte