Arquiteturas de aplicativos ativo-ativo com o MongoDB
Avalie esse Artigo
Determinar o melhor banco de dados para um aplicativo moderno a ser implantado em vários data centers requer uma avaliação cuidadosa para acomodar uma variedade de requisitos complexos de aplicativos. O banco de dados será responsável pelo processamento de leituras e gravações em várias regiões geográficas, replicando as alterações entre elas e fornecendo as mais altas garantias possíveis de disponibilidade, consistência e durabilidade. Mas nem todas as opções de tecnologia são iguais. Por exemplo, uma tecnologia de banco de dados pode oferecer uma garantia maior de disponibilidade e, ao mesmo tempo, garantias menores de consistência e durabilidade dos dados do que outra tecnologia. As compensações feitas por uma tecnologia de banco de dados individual afetarão o comportamento do aplicativo sobre o qual ela foi criada.
Infelizmente, há uma compreensão limitada entre muitos arquitetos de aplicativos sobre as compensações específicas feitas por vários bancos de dados modernos. A crença popular parece ser que, se um aplicativo precisar aceitar gravações simultaneamente em vários data centers, ele precisará usar um banco de dados multi-master, em que vários masters são responsáveis por uma única cópia ou partição dos dados. Isso é um equívoco e é agravado por uma compreensão limitada das implicações (potencialmente negativas) que essa escolha tem no comportamento do aplicativo.
Para fornecer alguma clareza sobre este tópico, esta publicação começará descrevendo as funcionalidades do banco de dados exigidas pelos aplicativos modernos de vários centros de dados. Em seguida, descreverá as categorias de arquiteturas de banco de dados usadas para realizar esses requisitos e resumirá os prós e contras de cada uma. Por fim, ela analisará especificamente o MongoDB e descreverá como ele se encaixa nessas categorias. Ela listará algumas das funcionalidades específicas e opções de design oferecidas pelo MongoDB que o tornam adequado para implantações de aplicativos globais.
Quando as organizações consideram a implantação de aplicativos em vários data centers (ou regiões de nuvem), geralmente desejam usar uma arquitetura ativa-ativa. Em alto nível, isso significa implantar um aplicativo em vários data centers, onde os servidores de aplicativos em todos os data centers processam solicitações simultaneamente (Figura 1). Essa arquitetura visa alcançar vários objetivos:
- Atender a um público distribuído globalmente, fornecendo processamento local (baixas latências)
- Manter a disponibilidade sempre ativa, mesmo diante de interrupções regionais completas
- Oferecer a melhor utilização dos recursos da plataforma, permitindo que os recursos do servidor em vários data centers sejam usados em paralelo para processar solicitações de aplicativos.
Uma alternativa para uma arquitetura ativa-ativa é uma arquitetura de recuperação ativa de desastres (também conhecida como ativa-passiva), que consiste em um data center primário (região) e uma ou mais regiões de recuperação de desastres (DR) (Figura 2). Em condições normais de operação, o data center primário processa solicitações e o centro DR fica ocioso. O site de DR só começa a processar solicitações (se torna ativo) se o data center primário falhar. (Sob situações normais, os dados são replicados do primário para os sites de DR, para que os sites de DR possam assumir o controle se o centro de dados primário falhar).
A definição de uma arquitetura ativa-ativa não é universalmente aceita. Frequentemente, ela também é usada para descrever arquiteturas de aplicativos semelhantes à arquitetura ativa de DR descrita acima, com a diferença de que o failover do site primário para o site de DR é rápido (normalmente alguns segundos) e automático (sem necessidade de intervenção humana). Nessa interpretação, uma arquitetura ativa-ativa indica que o tempo de inatividade do aplicativo é mínimo (próximo de zero).
Um equívoco comum é que uma arquitetura de aplicativo ativo-ativo requer um banco de dados multi-master. Isso não é apenas falso, mas usar um banco de dados multi-master significa relaxar os requisitos que a maioria dos proprietários de dados preza: consistência e durabilidade dos dados. A consistência garante que as leituras reflitam os resultados de gravações anteriores. A durabilidade dos dados garante que as gravações confirmadas persistam permanentemente: nenhum dado é perdido devido à resolução de gravações conflitantes ou falhas de nó. Esses dois requisitos de banco de dados são essenciais para criar aplicativos que se comportem da maneira previsível e determinística que os usuários esperam.
Para resolver o equívoco do multimestre, vamos começar analisando as várias arquiteturas de banco de dados que podem ser usadas para obter um aplicativo ativo-ativo e os prós e contras de cada uma. Depois disso, analisaremos a arquitetura do MongoDB e veremos como ela pode ser usada para implantar uma arquitetura de aplicativo ativo-ativo.
Ao projetar uma arquitetura de aplicativo ativo-ativo, o nível de banco de dados deve atender a quatro requisitos de arquitetura (além da funcionalidade padrão do banco de dados: linguagem de query avançada com índices secundários avançados, acesso de baixa latência aos dados, drivers nativos, ferramentas operacionais abrangentes etc.):
- Desempenho: baixa latência de leituras e gravações. Normalmente, isso significa processar leituras e gravações em nós em um data center local para o aplicativo.
- Durabilidade dos dados: implementada replicando gravações em vários nós para que os dados persistam quando ocorrerem falhas no sistema.
- Consistência - garantir que os leitores vejam os resultados de gravações anteriores, que os leitores de vários nós em diferentes regiões obtenham os mesmos resultados etc.
- Disponibilidade - o banco de dados deve continuar a operar quando nós, data centers ou falha de conexões de rede. Além disso, a recuperação dessas falhas deve ser a mais curta possível. Um requisito típico é de alguns segundos.
Devido às leis da física, como, por exemplo, a velocidade da luz, nenhum banco de dados pode satisfazer completamente todos esses requisitos ao mesmo tempo. Portanto, a consideração importante para qualquer equipe de engenharia que esteja criando um aplicativo é entender as compensações feitas por cada banco de dados e selecionar aquele que atenda aos requisitos mais críticos do aplicativo.
Vejamos cada um desses requisitos em mais detalhes.
Por motivos de desempenho, é necessário que os servidores de aplicativos em um data center possam realizar leituras e gravações em nós de banco de dados no mesmo data center, pois a maioria dos aplicativos exige tempos de resposta de milissegundos dos bancos de dados. A comunicação entre nós em vários data centers pode dificultar a obtenção de SLAs de desempenho. Se as leituras e gravações locais não forem possíveis, a latência associada ao envio de consultas a servidores remotos afetará significativamente o tempo de resposta do aplicativo. Por exemplo, os clientes na Austrália não esperariam ter uma experiência de usuário muito pior do que os clientes no leste dos EUA, onde está localizado o data center principal do fornecedor de comércio eletrônico. Além disso, a falta de largura de banda de rede entre os data centers também pode ser um fator limitante.
A replicação é um recurso essencial em um banco de dados distribuído. O banco de dados deve garantir que as gravações feitas em um nó sejam replicadas para os outros nós que mantêm réplicas do mesmo registro, mesmo que esses nós estejam em locais físicos diferentes. As garantias de velocidade de replicação e durabilidade dos dados fornecidas variam entre os bancos de dados e são influenciadas por:
- O conjunto de nós que aceitam gravações para um determinado registro
- As situações em que a perda de dados pode ocorrer
- Se são permitidas gravações conflitantes (duas gravações diferentes ocorrendo no mesmo registro em data centers diferentes, aproximadamente ao mesmo tempo) e como elas são resolvidas quando ocorrem
As garantias de consistência de um banco de dados distribuído variam significativamente. Essa variação depende de vários fatores, inclusive se os índices são atualizados atomicamente com os dados, os mecanismos de replicação usados, a quantidade de informações que os nós individuais têm sobre o status dos registros correspondentes em outros nós etc.
O nível mais fraco de consistência oferecido pela maioria dos bancos de dados distribuídos é a consistência eventual. Ela simplesmente garante que, eventualmente, se todas as gravações forem interrompidas, o valor de um registro em todos os nós do banco de dados acabará se fundindo para o mesmo valor. Ela fornece poucas garantias sobre se um processo de aplicativo individual lerá os resultados de sua gravação ou se o valor lido é o valor mais recente de um registro.
A garantia de consistência mais forte que pode ser fornecida por bancos de dados distribuídos sem impacto severo no desempenho é a consistência causal. Conforme descrito pela Wikipedia, a consistência causal fornece as seguintes garantias:
- Leia suas gravações: isso significa que as operações de gravação anteriores são indicadas e refletidas pelas operações de leitura a seguir.
- Leituras monotônicas: isso implica que é garantido que um conjunto cada vez maior de operações de gravação atualizado seja indicado por operações de leitura posteriores.
- Gravações seguem leituras: isso garante que as operações de gravação ocorram após as leituras pelas quais são influenciadas.
- Escritas monotônicas: isso garante que as operações de gravação devem ocorrer após outras gravações que devem precedê-las.
A maioria dos bancos de dados distribuídos fornecerá garantias de consistência entre consistência eventual e causal. Quanto mais próximo da consistência causal, mais um aplicativo se comportará conforme o esperado pelos usuários, por exemplo, as queries retornarão os valores de gravações anteriores, os dados não parecerão perdidos e os valores dos dados não mudarão de maneira não determinística.
A disponibilidade de um banco de dados descreve a capacidade do banco de dados de sobreviver à perda de um nó, de um data center ou de uma comunicação de rede. O grau em que o banco de dados continua processando leituras e gravações no evento de diferentes tipos de falhas e o tempo necessário para se recuperar de falhas determinam sua disponibilidade. Algumas arquiteturas permitem leituras e gravações em nós isolados do restante do cluster de banco de dados por uma partição de rede e, portanto, fornecem um alto nível de disponibilidade. Além disso, diferentes bancos de dados variam quanto ao tempo necessário para detectar e se recuperar de falhas, sendo que alguns exigem intervenção manual do operador para restaurar um cluster de banco de dados íntegro.
Há três grandes categorias de arquiteturas de banco de dados implantadas para atender a esses requisitos:
- Transações distribuídas usando confirmação de duas fases
- Multi-master, às vezes também chamado de "masterless"
- Banco de dados particionado (fragmentado) com vários primários, cada um responsável por uma partição exclusiva dos dados
Vejamos cada uma dessas opções em mais detalhes, bem como os pros e contras de cada uma.
Uma abordagem de transação distribuída atualiza todos os nós que contêm um registro como parte de uma única transação, em vez de fazer com que as gravações sejam feitas em um nó e, depois, (de forma assíncrona) replicadas em outros nós. A transação garante que todos os nós receberão a atualização ou a transação falhará e todos os nós voltarão ao estado anterior se houver algum tipo de falha.
Um protocolo comum para implementar essa funcionalidade é chamado de confirmação de duas fases. O protocolo de confirmação de duas fases garante durabilidade e consistência de vários nós, mas sacrifica o desempenho. O protocolo de confirmação de duas fases requer duas fases de comunicação entre todos os nós envolvidos na transação com solicitações e confirmações enviadas em cada fase da operação para garantir que cada nó confirme a mesma gravação ao mesmo tempo. Quando os nós de banco de dados são distribuídos em vários data centers, isso geralmente envia a latência de query do intervalo de milissegundos para o intervalo de vários segundos. A maioria dos aplicativos, especialmente aqueles em que os clientes são usuários (dispositivos móveis, navegadores da web, aplicativos clientes etc.) consideram esse nível de tempo de resposta inaceitável.
Um banco de dados multimestre é um banco de dados distribuído que permite que um registro seja atualizado em um dos muitos nós clusterizados possíveis. (As gravações geralmente são replicadas para que os registros existam em vários nós e em vários data centers). À primeira vista, um banco de dados multimestre parece ser a plataforma ideal para executar uma arquitetura ativo-ativo. Ele permite que cada servidor de aplicativos leia e grave em uma cópia local dos dados sem restrições. No entanto, ele tem sérias limitações quando se trata de consistência de dados.
O desafio é que duas (ou mais) cópias do mesmo registro possam ser atualizadas simultaneamente por sessões diferentes em locais diferentes. Isso leva a duas versões diferentes do mesmo registro e banco de dados, ou às vezes o próprio aplicativo deve executar a resolução de conflitos para resolver essa inconsistência. Na maioria das vezes, uma estratégia de resolução de conflitos, como as últimas atualizações bem sucedidas ou o registro com o maior número de modificações corretas, é usada, pois o desempenho seria significativamente afetado se alguma outra estratégia de resolução mais sofisticada fosse aplicada. Isso também significa que os leitores em diferentes data centers podem ver um valor diferente e conflitante para o mesmo registro no período entre a aplicação das gravações e a conclusão do mecanismo de resolução de conflitos.
Por exemplo, vamos supor que estejamos usando um banco de dados multimestre como armazenamento de persistência para um aplicativo de carrinho de compras e que esse aplicativo esteja implantado em dois data centers: Leste e Oeste. Quase ao mesmo tempo, um usuário em São Francisco adiciona um item ao carrinho de compras (uma lanterna), enquanto um processo de gerenciamento de inventário no data center do Leste invalida um item diferente do carrinho de compras (console de jogos) para esse mesmo usuário em resposta a uma notificação do fornecedor de que a data de lançamento foi adiada (veja os horários 0 a 1 na Figura 3).
No momento 1, os registros do carrinho de compras nos dois data centers são diferentes. O banco de dados usará seus mecanismos de replicação e resolução de conflitos para resolver essa inconsistência e, por fim, uma das duas versões do carrinho de compras (veja o momento 2 na Figura 3) será selecionada. Usando a heurística de resolução de conflitos mais frequentemente aplicada por bancos de dados multi-master (a última atualização vence ou a mais atualizada vence), é impossível para o usuário ou aplicativo prever qual versão será selecionada. Em ambos os casos, os dados são perdidos e ocorrem comportamentos inesperados. Se a versão Leste for selecionada, a seleção de uma lanterna pelo usuário será perdida e, se a versão Oeste for selecionada, o console de jogos ainda estará no carrinho. De qualquer forma, informações são perdidas. Finalmente, qualquer outro processo que inspecione o carrinho de compras entre os momentos 1 e 2 também será comportamento não determinístico. Por exemplo, um processo em segundo plano que seleciona o centro de distribuição e atualiza os custos de envio do carrinho produziria resultados que entrariam em conflito com o conteúdo eventual do carrinho. Se o processo estiver sendo executado no Oeste e a alternativa 1 se tornar realidade, ela calculará os custos de envio de todos os três itens, mesmo que o carrinho possa ter em breve apenas um item, o livro.
O conjunto de casos de uso para bancos de dados multimestre é limitado à captura de dados não críticos para a tarefa, como dados de registro, onde a perda eventual de registro é aceitável. A maioria dos casos de uso não pode tolerar a combinação de perda de dados resultante do descarte de uma versão de um registro durante a resolução de conflitos e leituras inconsistentes que ocorrem durante esse processo.
Um banco de dados particionado divide o banco de dados em partições, chamadas fragmentos. Cada fragmento é implementado por um conjunto de servidores, cada um dos quais contém uma cópia completa dos dados da partição. O importante aqui é que cada fragmento mantém o controle exclusivo de sua partição dos dados. A qualquer momento, para cada fragmento, um servidor atua como primário e os outros servidores atuam como réplicas secundárias. Leituras e gravações são emitidas para a cópia primária dos dados. Se o servidor primário falhar por qualquer motivo (por exemplo, falha de hardware, partição de rede), um dos servidores secundários será automaticamente eleito para o principal.
Cada registro no banco de dados pertence a uma partição específica e é gerenciado por exatamente um fragmento, garantindo que ele só possa ser gravado no primário do fragmento. O mapeamento de registros para fragmentos e a existência de exatamente um primário por fragmento garantem consistência. Como o cluster contém vários fragmentos e, portanto, vários primários (vários mestres), esses primários podem ser distribuídos entre os data centers para garantir que as gravações ocorram localmente em cada data center (Figura 4).
Um banco de dados fragmentado pode ser usado para implementar uma arquitetura de aplicativo ativo-ativo, implantando pelo menos tantos fragmentos quanto data centers e colocando os primários para os fragmentos de modo que cada data center tenha pelo menos um primário (Figura 5). Além disso, os fragmentos são configurados de forma que cada um tenha pelo menos uma réplica (cópia dos dados) em cada um dos datacenters. Por exemplo, o diagrama na Figura 5 representa uma arquitetura de banco de dados distribuída em três datacenters: Nova York (NYC), Londres (LON) e Sydney (SYD). O cluster tem três fragmentos, onde cada fragmento tem três réplicas.
- O fragmento NYC tem um primário em Nova York e secundários em Londres e Sydney
- O fragmento LON tem um primário em Londres e secundários em Nova York e Sydney
- O fragmento SYD tem um primário em Sydney e secundários em Nova York e Londres
Dessa forma, cada data center tem secundários de todos os fragmentos para que os servidores de aplicativos locais possam ler todo o conjunto de dados e um primário para um fragmento para que as gravações também possam ser feitas localmente.
O banco de dados fragmentado atende à maioria dos requisitos de consistência e desempenho para a maioria dos casos de uso. O desempenho é excelente porque as leituras e gravações ocorrem em servidores locais. Ao ler dos primários, a consistência é garantida, pois cada registro é atribuído a exatamente um primário. Essa opção requer a arquitetura do aplicativo para que os usuários/queries sejam roteados para o data center que gerencia os dados (contém o primário) para a query. Freqqentemente, isso é feito por meio da geografia. Por exemplo, se tivermos dois data centers nos Estados Unidos (Nova Jersey e Oregon), poderemos fragmentar o conjunto de dados por região geográfica (Leste e Oeste) e rotear o tráfego dos usuários da Costa Leste para o data center de Nova Jersey, que contém o primário do fragmento Leste, e rotear o tráfego dos usuários da Costa Oeste para o data center do Oregon, que contém o primário do fragmento Oeste.
Vamos rever o exemplo do carrinho de compras usando um banco de dados fragmentado. Novamente, vamos supor dois data centers: Leste e Oeste. Para essa implementação, fragmentaríamos (particionaríamos) os carrinhos de compras pelo ID do cartão de compras, além de um campo de data center identificando o data center no qual o carrinho de compras foi criado. O particionamento (Figura 6) garantiria que todos os carrinhos de compras com um valor de campo DataCenter de "Leste" fossem gerenciados pelo fragmento com o primário no data center Oeste. O outro fragmento gerenciaria carrinhos com o valor de "Oeste". Além disso, precisaríamos de duas instâncias do serviço de gerenciamento de inventário, uma implantada em cada data center, com a responsabilidade de atualizar os carrinhos de propriedade do data center local.
Esse design pressupõe que haja algum processo externo roteando o tráfego para o data center correto. Quando um novo carrinho for criado, a sessão do usuário será roteada para o data center geograficamente mais próximo e, em seguida, atribuirá um valor de DataCenter para esse data center. Para um carrinho existente, o roteador pode usar o campo DataCenter do carrinho para identificar o data center correto.
Neste exemplo, podemos ver que o banco de dados fragmentado nos oferece todos os benefícios de um banco de dados multi-master sem as complexidades decorrentes da inconsistência de dados. Os servidores de aplicativos podem ler e gravar a partir do primário local, mas como cada carrinho pertence a um único primário, nenhuma inconsistência pode ocorrer. Por outro lado, as soluções multi-master têm o potencial de perda de dados e leituras inconsistentes.
Os pros e contras de quão bem cada arquitetura de banco de dados atende aos requisitos de aplicativo ativo-ativo são fornecidos na Figura 7. Ao escolher entre bancos de dados multi-master e bancos de dados fragmentados, a decisão se resume ao fato de o aplicativo poder ou não tolerar leituras potencialmente inconsistentes e perda de dados. Se a resposta for sim, então um banco de dados multi-master pode ser um pouco mais fácil de implantar. Se a resposta for não, um banco de dados fragmentado é a melhor opção. Como a inconsistência e a perda de dados não são aceitáveis para a maioria dos aplicativos, um banco de dados fragmentado geralmente é a melhor opção.
O MongoDB é um exemplo de uma arquitetura de banco de dados fragmentada. No MongoDB, a construção de um servidor primário e um conjunto de servidores secundários é chamada de conjunto de réplicas. Os conjuntos de réplicas fornecem alta disponibilidade para cada fragmento e um mecanismo, chamado Fragmentação de zona, é usado para configurar o conjunto de dados gerenciados por cada fragmento. A fragmentação de zona torna possível implementar o particionamento geográfico descrito na seção anterior. Os detalhes de como fazer isso estão descritos no white paper Implantações do MongoDB em múltiplos data centers e na documentação da Fragmentação de zona, mas o MongoDB opera conforme descrito na seção "Banco de dados particionado (fragmentado)".
Inúmeras organizações usam o MongoDB para implementar arquiteturas de aplicativos ativo-ativo. Por exemplo:
- O Ebay codificou o uso de fragmentação de zona para permitir leituras e gravações locais como um de seus padrões de arquitetura padrão.
- O YouGov implanta o MongoDB em seu sistema de pesquisa principal, chamado Gryfon, em um padrão de "gravação local, leitura global" que facilita implantações ativo-ativo de vários data centers na América do Norte e na Europa.
- A Ogilvy & Mather usa o MongoDB como armazenamento de persistência para seu aplicativo principal de auditoria. Seu cluster fragmentado abrange três centros de dados na América do Norte e na Europa, com data centers ativos na América do Norte e na Europa continental e um centro de dados de DR em Londres. Essa arquitetura minimiza a latência de gravação e também oferece suporte a leituras locais para análises e relatórios centralizados de todo o conjunto de dados.
Além da funcionalidade padrão de banco de dados fragmentado, o MongoDB fornece controles de granulação fina para durabilidade de gravação e consistência de leitura que o tornam ideal para implantações de vários data centers. Para gravações, uma preocupação de gravação pode ser especificada para controlar a durabilidade da gravação. A preocupação de gravação permite que o aplicativo especifique o número de membros do conjunto de réplicas que devem aplicar a gravação antes que o MongoDB reconheça a gravação no aplicativo. Ao fornecer uma preocupação de gravação, um aplicativo pode ter certeza de que, quando o MongoDB reconhece a gravação, os servidores em um ou mais data centers remotos também aplicaram a gravação. Isso garante que as alterações no banco de dados não serão perdidas no evento de falha do nó ou do data center.
Além disso, o MongoDB aborda uma das possíveis desvantagens de um banco de dados fragmentado: menos de 100% de disponibilidade de gravação. Como há somente um primário para cada registro, se esse primário falhar, haverá um período em que as gravações na partição não poderão ocorrer. O MongoDB combina tempos de failover extremamente rápidos com gravações repetíveis. Com gravações repetíveis, o MongoDB fornece suporte automatizado para a repetição de gravações que falharam devido a erros transitórios do sistema, como falhas de rede ou eleições primárias, simplificando significativamente o código do aplicativo.
A velocidade do failover automatizado do MongoDB é outro recurso distintivo que torna o MongoDB ideal para implantações de vários data centers. O MongoDB pode fazer o failover em 2-5 segundos (dependendo da configuração e da confiabilidade da rede), quando um nó ou data center falha ou ocorre uma divisão da rede. (Observe que as leituras secundárias podem continuar durante o período de failover.) Depois que ocorrer uma falha, os membros restantes do conjunto de réplicas escolherão um novo primário e o driver do MongoDB, no qual a maioria dos aplicativos é criada, identificará automaticamente esse novo primário. O processo de recuperação é automático e as gravações continuam após a conclusão do processo de failover.
Para leituras, o MongoDB fornece duas funcionalidades para especificar o nível de consistência desejado. Primeiro, ao ler a partir de secundários, um aplicativo pode especificar um valor máximo de atraso (maxStalenessSeconds). Isso garante que o atraso de replicação do secundário em relação ao primário não possa ser maior do que a duração especificada e, portanto, garante a atualidade dos dados retornados pelo secundário. Além disso, uma leitura também pode ser associada a um ReadConcern para controlar a consistência dos dados retornados pela query. Por exemplo, um ReadConcern da maioria diz ao MongoDB para retornar apenas dados que foram replicados para a maioria dos nós no conjunto de réplicas. Isso garante que a query esteja lendo apenas dados que não serão perdidos devido a uma falha de nó ou data center e dá ao aplicativo uma exibição consistente dos dados ao longo do tempo.
O MongoDB 3.6 também introduziu consistência causal - garantindo que cada operação de leitura em uma sessão de cliente sempre veja a operação de gravação anterior, independentemente de qual réplica esteja atendendo à solicitação. Ao impor uma ordem causal estrita de operações em uma sessão, a consistência causal garante que cada leitura seja sempre logicamente consistente, permitindo leituras monotônicas de um sistema distribuído - garantias que não podem ser atendidas pela maioria dos bancos de dados com vários nós. A consistência causal permite que os desenvolvedores mantenham os benefícios da consistência rigorosa de dados imposta por bancos de dados relacionais de nó único legado, enquanto modernizam sua infraestrutura para aproveitar os benefícios de escalabilidade e disponibilidade de plataformas de dados distribuídos modernas.
Nesta publicação, mostramos que os bancos de dados fragmentados fornecem o melhor suporte para os requisitos de replicação, desempenho, consistência, gravação local e leitura local de aplicativos ativos-ativos. O desempenho de bancos de dados de transações distribuídas é muito lento e os bancos de dados multi-master não fornecem as garantias de consistência necessárias. Além disso, o MongoDB é especialmente adequado para sistemas de vários centros de dados devido à sua arquitetura distribuída, failover rápido e capacidade dos aplicativos especificarem garantias de consistência e durabilidade desejadas por meio de preocupações de leitura e gravação.