Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Este artigo descreve considerações para gerenciar dados em uma arquitetura de microsserviços. Cada microserviço gere os seus próprios dados, pelo que a integridade e consistência dos dados representam desafios críticos.
Dois serviços não deveriam partilhar um armazenamento de dados. Cada serviço gere o seu próprio armazenamento privado de dados, e outros serviços não podem aceder diretamente a ele. Esta regra previne o acoplamento não intencional entre serviços, que acontece quando os serviços partilham os mesmos esquemas de dados subjacentes. Se o esquema de dados mudar, a alteração deve ser coordenada por todos os serviços que dependem dessa base de dados. Isolar o armazenamento de dados de cada serviço limita o âmbito da alteração e preserva a agilidade das implementações independentes. Cada microserviço pode também ter modelos de dados únicos, consultas ou padrões de leitura e escrita. Um armazenamento de dados partilhado limita a capacidade de cada equipa de otimizar o armazenamento de dados para o seu serviço específico.
O diagrama mostra o serviço A e uma base de dados numa secção à esquerda. Uma seta com a etiqueta "escrever" aponta do serviço A para a base de dados. O Serviço B situa-se fora desta secção à direita. Uma seta rotulada como 'read' aponta para a base de dados. Um X vermelho cruza esta seta.
Esta abordagem conduz naturalmente à persistência poliglota, o que significa usar múltiplas tecnologias de armazenamento de dados numa única aplicação. Um serviço pode precisar das capacidades de esquema ao ler de uma base de dados documental. Outro serviço pode necessitar da integridade referencial que um sistema de gestão de bases de dados relacional (SGBD) proporciona. Cada equipa pode escolher a melhor opção para o seu serviço.
Observação
Os serviços podem partilhar em segurança o mesmo servidor físico de base de dados. Os problemas surgem quando os serviços partilham o mesmo esquema ou leem e escrevem para o mesmo conjunto de tabelas de base de dados.
Desafios
A abordagem distribuída à gestão de dados apresenta vários desafios. Em primeiro lugar, pode ocorrer redundância em vários repositórios de dados. O mesmo elemento de dados pode aparecer em vários locais. Por exemplo, os dados podem ser armazenados como parte de uma transação e depois armazenados noutro local para análise, relatórios ou arquivamento. Dados duplicados ou particionados podem levar a problemas de integridade e consistência dos dados. Quando as relações de dados abrangem múltiplos serviços, as técnicas tradicionais de gestão de dados não conseguem impor essas relações.
A modelação tradicional de dados segue a regra de um facto num só lugar. Cada entidade aparece exatamente uma vez no esquema. Outras entidades podem mencioná-lo, mas não duplicá-lo. A principal vantagem da abordagem tradicional é que as atualizações ocorrem num único local, o que previne problemas de consistência de dados. Numa arquitetura de microserviços, deve considerar como as atualizações se propagam entre os serviços e como gerir a consistência eventual quando os dados aparecem em vários locais sem uma consistência forte.
Abordagens para gerenciar dados
Nenhuma abordagem única funciona para todos os casos. Considere as seguintes diretrizes gerais para gerir dados numa arquitetura de microserviços:
Defina o nível de consistência exigido para cada componente e prefira consistência eventual sempre que possível. Identifique áreas no sistema onde precisa de transações de forte consistência ou atomicidade, consistência, isolamento e durabilidade (ACID). E identificar áreas onde a consistência eventual seja aceitável. Para mais informações, consulte Utilizar design tático orientado por domínio (DDD) para microserviços.
Use uma única fonte de verdade quando precisar de forte consistência. Um serviço pode representar a fonte de verdade para uma dada entidade e expô-la através de uma API. Outros serviços podem conter a sua própria cópia dos dados, ou um subconjunto dos dados, que eventualmente é consistente com os dados primários mas não é considerado a fonte da verdade. Por exemplo, num sistema de comércio eletrónico que tenha um serviço de encomenda ao cliente e um serviço de recomendação, o serviço de recomendação pode ouvir eventos do serviço de encomenda. Mas se um cliente pedir reembolso, o serviço de encomenda, e não o serviço de recomendação, tem o histórico completo das transações.
Aplique padrões de transação para manter a consistência entre os serviços. Use padrões como Scheduler Agent Supervisor e Transação de Compensação para manter os dados consistentes em múltiplos serviços. Para evitar falhas parciais entre múltiplos serviços, pode ser necessário armazenar um dado extra que capture o estado de uma unidade de trabalho que abrange vários serviços. Por exemplo, mantenha um item de trabalho em uma fila durável enquanto uma transação de várias etapas estiver em andamento.
Armazene apenas os dados de que um serviço precisa. Um serviço pode precisar apenas de um subconjunto de informações sobre uma entidade de domínio. Por exemplo, no contexto delimitado de envio, precisa de saber qual o cliente está associado a uma entrega específica. Mas não precisas do endereço de faturação do cliente porque o contexto limitado da conta gere essa informação. Uma análise cuidadosa do domínio e uma abordagem DDD podem impor este princípio.
Considere se os seus serviços são coerentes e estão ligados de forma flexível. Se dois serviços trocarem continuamente informações entre si e criarem APIs comunicativas, poderá ser necessário redesenhar os limites dos seus serviços. Junte os dois serviços ou refatore a sua funcionalidade.
Use um estilo arquitetónico orientado por eventos. Neste estilo arquitetónico, um serviço publica um evento quando ocorrem alterações nos seus modelos ou entidades públicas. Outros serviços podem subscrever estes eventos. Por exemplo, outro serviço pode usar os eventos para construir uma visão materializada dos dados mais adequada para consultas.
Publica um esquema para eventos. Um serviço que detém eventos deve publicar um esquema para automatizar a serialização e desserialização dos eventos. Esta abordagem evita uma ligação estreita entre editores e assinantes. Considere o esquema JSON ou um framework como o Protobuf ou o Avro.
Reduzir os gargalos de eventos em grande escala. Em grande escala, os eventos podem tornar-se um gargalo no sistema. Considere usar agregação ou agrupamento para reduzir a carga total.
Exemplo: Escolher armazenamentos de dados para a aplicação de entrega de drones
Os artigos anteriores desta série descrevem um serviço de entrega por drone como um exemplo recorrente. Para mais informações sobre o cenário e a arquitetura correspondente, veja Projetar uma arquitetura de microserviços.
Para recapitular, esta aplicação define vários microsserviços para agendar entregas por drone. Quando um utilizador agenda uma nova entrega, o pedido do cliente inclui informações sobre a entrega, como locais de recolha e entrega, e sobre a encomenda, como tamanho e peso. Esta informação define uma unidade de trabalho.
Os vários serviços de back-end utilizam diferentes partes da informação no pedido e têm diferentes perfis de leitura e escrita.
Serviço de entrega
O serviço de entregas armazena informações sobre todas as entregas que estão atualmente agendadas ou em andamento. Escuta os eventos dos drones e acompanha o estado das entregas em curso. Ele também envia eventos de domínio com atualizações de status de entrega.
Os utilizadores verificam frequentemente o estado de uma entrega enquanto esperam pela encomenda. Assim, o serviço de entrega requer um armazenamento de dados que enfatize o throughput (leitura e escrita) em detrimento do armazenamento a longo prazo. O serviço de entrega não faz consultas ou análises complexas. Só obtém o estado mais recente para uma entrega específica. A equipa de serviço de entrega escolheu o Azure Managed Redis pelo seu elevado desempenho de leitura e escrita. A informação armazenada no Azure Managed Redis é de curta duração. Após o término da entrega, o serviço de histórico de entregas torna-se o sistema de registo.
Serviço de histórico de entregas
O serviço de histórico de entregas escuta os eventos de estado da entrega do serviço de entrega. Ele armazena esses dados em armazenamento de longo prazo. Estes dados históricos suportam dois cenários, cada um com requisitos de armazenamento diferentes.
O primeiro cenário agrega dados para análise de dados para otimizar o negócio ou melhorar a qualidade do serviço. O serviço de histórico de entregas não faz a análise real dos dados. Apenas ingere e armazena os dados. Neste cenário, o armazenamento deve ser otimizado para análise de dados em grandes volumes de dados e seguir a abordagem de 'esquema à leitura' para acomodar várias fontes de dados. O Azure Data Lake Storage é uma boa opção para este cenário porque é um sistema de ficheiros Apache Hadoop compatível com o Hadoop Distributed File System (HDFS). Também está ajustado para o desempenho em cenários de análise de dados.
O segundo cenário permite aos utilizadores consultar o histórico de uma entrega após o término da entrega. O Data Lake Storage não suporta este cenário. Para um desempenho ótimo, armazene dados de séries temporais no Data Lake Storage em pastas particionadas por data. Mas esta estrutura torna as pesquisas individuais baseadas em ID ineficientes. A menos que também saibas o carimbo temporal, uma consulta de identificação exige que digitalizes toda a coleção. Para resolver este problema, o serviço de histórico de entregas também armazena um subconjunto dos dados históricos no Azure Cosmos DB para uma pesquisa mais rápida. Os registros não precisam permanecer no Azure Cosmos DB indefinidamente. Pode arquivar entregas antigas após um período específico, como um mês, executando um processo em lote ocasional. Arquivar dados pode reduzir custos para o Azure Cosmos DB e manter os dados disponíveis para relatórios históricos a partir do Data Lake Storage.
Para mais informações, consulte Otimizar Data Lake Storage para melhorar o desempenho.
Serviço de encomendas
O serviço de encomendas armazena informações sobre todas as encomendas. O armazenamento de dados do serviço de encomendas deve cumprir os seguintes requisitos:
- Armazenamento a longo prazo
- Alta capacidade de escrita para lidar com um grande volume de pacotes
- Consultas simples por ID de pacote sem joins complexas ou restrições de integridade referencial
Os dados do pacote não são relacionais, por isso uma base de dados orientada a documentos funciona bem. O Azure DocumentDB pode alcançar um alto rendimento utilizando coleções sharded. A equipa de serviços de pacotes está familiarizada com a pilha MongoDB, Express.js, AngularJS e Node.js (MEAN), por isso optaram por implementar o Azure DocumentDB. Esta escolha permite-lhes usar a sua experiência existente no MongoDB, beneficiando dos benefícios de um serviço Azure totalmente gerido e de alto desempenho.