Microsserviços e junções de banco de dados


112

Para as pessoas que estão dividindo aplicativos monolíticos em microsserviços, como lidar com o problema de quebrar o banco de dados? Os aplicativos típicos nos quais trabalhei fazem muita integração de banco de dados por motivos de desempenho e simplicidade.

Se você tem duas tabelas que são logicamente distintas (contextos limitados, se preferir), mas costuma agregar o processamento em grandes volumes desses dados, no monólito é mais do que provável que você evite a orientação a objetos e, em vez disso, use o padrão do seu banco de dados Recurso JOIN para processar os dados no banco de dados antes de retornar a visualização agregada de volta à camada do seu aplicativo.

Como você justifica a divisão desses dados em microsserviços onde, presumivelmente, você será obrigado a 'unir' os dados por meio de uma API em vez de no banco de dados?

Eu li o livro Microservices de Sam Newman e no capítulo sobre a divisão do Monolith ele dá um exemplo de "Breaking Foreign Key Relationships", onde ele reconhece que fazer uma junção em uma API vai ser mais lento - mas ele continua dizendo se seu aplicativo é rápido o suficiente de qualquer maneira, faz diferença se ele está mais lento do que antes?

Isso parece um pouco simplista? Quais são as experiências das pessoas? Quais técnicas você usou para fazer as junções de API funcionarem de maneira aceitável?


2
Boa pergunta, estou passando pelo mesmo problema e acabei tendo uma view materializada e fazendo joins nisso. Não gosto, mas acho que vai ser um desafio com Micro Services. Não existe uma maneira certa de fazer isso, é apenas uma escolha de design a ser feita. Sei que muitas pessoas dizem que podemos ter uma visão materializada, mas as respostas agregadas se tornam um problema. Deixe-me saber se você encontrou algo melhor.
PavanSandeep de

Eu sei que isso é antigo, mas isso é algo que o Graphql resolve? Também estou procurando uma migração segmentada e parece que o graphql é a maneira de fazer isso sem problemas.
themightybun

Em algum ponto, você deve perceber que ser dogmático não é o caminho a seguir. GraphQL é um exemplo decente de fazer agregação fora da fonte de dados e geralmente funciona bem.
Christian Ivicevic

Respostas:


26
  • Quando o desempenho ou a latência não importa muito (sim, nem sempre precisamos deles), é perfeitamente normal apenas usar APIs RESTful simples para consultar os dados adicionais de que você precisa. Se você precisar fazer várias chamadas para microsserviços diferentes e retornar um resultado, poderá usar o padrão API Gateway .

  • É perfeitamente normal ter redundância em ambientes de persistência poliglota . Por exemplo, você pode usar a fila de mensagens para seus microsserviços e enviar eventos de "atualização" sempre que mudar algo. Outros microsserviços ouvirão os eventos necessários e salvarão os dados localmente. Portanto, em vez de consultar, você mantém todos os dados necessários no armazenamento apropriado para microsserviços específicos.

  • Além disso, não se esqueça do cache :) Você pode usar ferramentas como Redis ou Memcached para evitar consultar outros bancos de dados com muita frequência.


25
Todas boas sugestões, mas ainda acho difícil de racionalizar, Talvez seja porque estamos tão acostumados a fazer muito processamento no banco de dados. Nosso aplicativo atual tem procedimentos armazenados complicados que processam grandes volumes de dados e, em seguida, retornam um pequeno conjunto de resultados. Em uma arquitetura de microsserviços, eu acho que essas entidades devem ser divididas em diferentes contextos limitados. Sabemos que a abordagem atual é feia, mas é difícil justificar trazer todos os dados de volta para a camada de aplicativo para processá-los. Talvez mais desnormalização ou visualizações agregadas pré-computacionais ajudem.
Martin Bayly

1
Sim, entendo. A abordagem de microsserviços não é para todos e você deve aplicá-la com cuidado. Provavelmente você pode começar com mudanças menores.
sap1ens

Provavelmente, os programadores StackExchange teriam sido um lugar melhor para fazer esta pergunta: programmers.stackexchange.com/questions/279409/… e outras questões marcadas como microsserviços programmers.stackexchange.com/questions/tagged/microservices
Martin Bayly

9

É normal que os serviços tenham cópias replicadas somente leitura de determinados dados de referência de outros serviços.

Dado que, ao tentar refatorar um banco de dados monolítico em microsserviços (em vez de reescrever), eu

  • crie um esquema db para o serviço
  • criar * visualizações ** com versão nesse esquema para expor os dados desse esquema a outros serviços
  • fazer junções nessas visualizações somente leitura

Isso permitirá que você modifique os dados / estrutura da tabela de forma independente, sem quebrar outros aplicativos.

Em vez de usar visualizações, também posso considerar o uso de gatilhos para replicar dados de um esquema para outro.

Isso seria um progresso incremental na direção certa, estabelecendo as costuras de seus componentes, e uma mudança para REST pode ser feita mais tarde.

* as visualizações podem ser estendidas. Se uma alteração significativa for necessária, crie uma v2 da mesma visualização e remova a versão antiga quando não for mais necessária. ** ou funções com valor de tabela ou Sprocs.


5

CQRS --- Padrão de agregação de consulta de comando é a resposta a essa pergunta de acordo com Chris Richardson. Deixe cada microsserviço atualizar seu próprio modelo de dados e gerar os eventos que atualizarão a visualização materializada com os dados de junção necessários de microsserviços anteriores. Este MV pode ser qualquer banco de dados NoSql ou Redis ou elasticsearch otimizado para consulta. Essa técnica leva à consistência Eventual que definitivamente não é ruim e evita as junções do lado do aplicativo em tempo real. Espero que isso responda.


2

Eu separaria as soluções para a área de uso, digamos operacional e reporting.

Para os microsserviços que operam para fornecer dados para formulários únicos que precisam de dados de outros microsserviços (este é o caso operacional), acho que usar junções de API é o caminho a percorrer. Você não vai buscar grandes quantidades de dados, você pode fazer integração de dados no serviço.

O outro caso é quando você precisa fazer grandes consultas em uma grande quantidade de dados para fazer agregações etc. (o caso de relatório). Para essa necessidade, eu pensaria em manter um banco de dados compartilhado - semelhante ao seu esquema original e atualizá-lo com eventos de seus bancos de dados de microsserviço. Neste banco de dados compartilhado, você pode continuar a usar seus procedimentos armazenados, o que economiza seus esforços e oferece suporte às otimizações do banco de dados.


1

Em microsserviços você cria diferenças. leia os modelos, por exemplo: se você tiver dois diff. contexto limitado e alguém deseja pesquisar os dados, então alguém precisa ouvir os eventos do contexto limitado e criar uma visualização específica para o aplicativo.

Nesse caso, haverá mais espaço necessário, mas nenhuma junção será necessária e nenhuma junção.

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.