Onde mongodb se posiciona no teorema CAP?

121

Para onde quer que eu olhe, vejo que MongoDB é CP. Mas quando eu cavo, vejo que eventualmente é consistente. É CP quando você usa safe = true? Em caso afirmativo, isso significa que quando escrevo com safe = true, todas as réplicas serão atualizadas antes de obter o resultado?

Gluz
fonte

Respostas:

104

O MongoDB é fortemente consistente por padrão - se você fizer uma gravação e depois uma leitura, presumindo que a gravação foi bem-sucedida, você sempre será capaz de ler o resultado da gravação que acabou de ler. Isso ocorre porque o MongoDB é um sistema de mestre único e todas as leituras vão para o primário por padrão. Se você opcionalmente habilitar a leitura dos secundários, o MongoDB se tornará eventualmente consistente, onde é possível ler resultados desatualizados.

O MongoDB também obtém alta disponibilidade por meio de failover automático em conjuntos de réplicas: http://www.mongodb.org/display/DOCS/Replica+Sets

Stbrody
fonte
13
De acordo com aphyr.com/posts/322-call-me-maybe-mongodb-stale-reads, mesmo se você ler do nó primário no conjunto de réplicas, poderá obter dados obsoletos ou sujos. Então, o MongoDB forte é consistente ??
Mike Argyriou
3
Experimentos incríveis de Kyle. Ele realmente caça mongo. Gostaria de saber se existem sistemas de produção, por exemplo, usando MongoDB para fazer transações de pagamento? Se for apenas um site pessoal, quem se preocupa com a consistência forte então.
xin
5
Apenas para registro, MongoDB v3.4 passou no teste projetado por Kyle, então sim, MongoDB é fortemente consistente, mesmo com ReplicaSet e Sharding: mongodb.com/mongodb-3.4-passes-jepsen-test
Maxime Beugnet
2
Essa resposta pode ser um pouco simplista, pois o MongoDB pode sacrificar a disponibilidade de tempos em tempos, com base na configuração. JoCa's explica melhor as situações em que se comporta CA / CP / AP
PaoloC
36

Eu concordo com a postagem de Luccas. Você não pode simplesmente dizer que MongoDB é CP / AP / CA, porque na verdade é uma troca entre C, A e P, dependendo da configuração do banco de dados / driver e do tipo de desastre : aqui está uma recapitulação visual, e abaixo um explicação mais detalhada.

    Scenario                   | Main Focus | Description
    ---------------------------|------------|------------------------------------
    No partition               |     CA     | The system is available 
                               |            | and provides strong consistency
    ---------------------------|------------|------------------------------------
    partition,                 |     AP     | Not synchronized writes 
    majority connected         |            | from the old primary are ignored                
    ---------------------------|------------|------------------------------------
    partition,                 |     CP     | only read access is provided
    majority not connected     |            | to avoid separated and inconsistent systems

Consistência:

O MongoDB é fortemente consistente quando você usa uma única conexão ou o Nível de preocupação de gravação / leitura correto (o que vai custar sua velocidade de execução ). Assim que você não atender a essas condições (especialmente quando estiver lendo de uma réplica secundária), o MongoDB se torna eventualmente consistente.

Disponibilidade:

O MongoDB obtém alta disponibilidade por meio de conjuntos de réplicas . Assim que o primário cair ou ficar indisponível, os secundários determinarão que um novo primário ficará disponível novamente. Há uma desvantagem nisso: cada gravação realizada pelo antigo primário, mas não sincronizada com os secundários, será revertida e salva em um arquivo de rollback, assim que se reconectar ao conjunto (o primário antigo é um secundário agora). Portanto, neste caso, alguma consistência é sacrificada por uma questão de disponibilidade.

Tolerância de partição:

Através do uso dos referidos conjuntos de réplicas, o MongoDB também atinge a tolerância de partição: desde que mais da metade dos servidores de um conjunto de réplicas estejam conectados uns aos outros, um novo primário pode ser escolhido . Por quê? Para garantir que duas redes separadas não possam escolher um novo primário. Quando não há secundários suficientes conectados entre si, você ainda pode ler a partir deles (mas a consistência não é garantida), mas não escrever. O conjunto está praticamente indisponível por uma questão de consistência.

JoCa
fonte
Portanto, se estou usando o nível de preocupação de gravação / leitura correto, isso significa que todas as escritas e leituras vão para o primário (se entendi corretamente), então o que exatamente os secundários fazem? Ficar sentado em espera caso o primário caia?
tomer.z
@ tomer.z você pode querer ler esta seção do manual: Você pode usar secundários para leitura. Se você estiver usando o nível de leitura "majoritário", a leitura será válida assim que a maioria dos membros reconhecer a leitura. O mesmo vale para o Nível de Gravação da "maioria". Se você estiver usando o nível de preocupação "majoritário" para ambos, terá um banco de dados consistente. Você pode querer ler mais sobre isso no manual .
JoCa de
18

Como um novo artigo brilhante apareceu e também alguns experimentos incríveis de Kyle neste campo, você deve ter cuidado ao rotular o MongoDB e outros bancos de dados como C ou A.

É claro que o CAP ajuda a rastrear sem muitas palavras o que o banco de dados prevalece sobre ele, mas as pessoas freqüentemente esquecem que C no CAP significa consistência atômica (linearização), por exemplo. E isso me causou muita dor para entender ao tentar classificar. Então, além do MongoDB dar consistência forte, isso não quer dizer que seja C. Desta forma, se fizermos essas classificações, recomendo também dar mais detalhes de como realmente funciona para não deixar dúvidas.

Luccas
fonte
10

Sim, é CP ao usar safe=true . Isso significa simplesmente que os dados foram para o disco mestre. Se você quiser ter certeza de que ele também chegou em alguma réplica, observe o parâmetro 'w = N', onde N é o número de réplicas nas quais os dados devem ser salvos.

veja isto e isto para mais informações.

Jan Prieser
fonte
3

Não tenho certeza sobre P para Mongo. Imagine a situação:

  • Sua réplica é dividida em duas partições.
  • As gravações continuam para ambos os lados, à medida que novos mestres foram eleitos
  • A partição foi resolvida - todos os servidores agora estão conectados novamente
  • O que acontece é que o novo mestre é eleito - aquele que tem o oplog mais alto, mas os dados do outro mestre são revertidos para o estado comum antes da partição e são despejados em um arquivo para recuperação manual
  • todos os secundários alcançam o novo mestre

O problema aqui é que o tamanho do arquivo de despejo é limitado e se você teve uma partição por muito tempo, pode perder seus dados para sempre.

Você pode dizer que é improvável que aconteça - sim, a menos que na nuvem, onde é mais comum do que se possa imaginar.

Este exemplo é porque eu seria muito cuidadoso antes de atribuir qualquer carta a qualquer banco de dados. Existem tantos cenários e implementações que não são perfeitas.

Se alguém souber se esse cenário foi abordado em versões posteriores do Mongo, comente! (Faz algum tempo que não acompanho tudo o que está acontecendo ..)

kubal5003
fonte
2
O protocolo de eleição do MongoDB é projetado para ter (no máximo) um único primário. Um primário só pode ser eleito (e mantido) por uma maioria estrita de membros votantes do conjunto de réplicas configurado (n / 2 +1). No caso de uma partição de rede, apenas uma partição (com a maioria dos membros votantes) pode eleger um primário; um primário anterior em uma partição minoritária deixará o cargo e se tornará um secundário. É assim que os conjuntos de réplicas sempre funcionaram. No caso de um antigo primário aceitar gravações que não foram replicadas, elas serão revertidas (salvas no disco) quando esse membro se juntar novamente ao conjunto de réplicas.
Stennie
2

O Mongodb nunca permite a gravação no secundário. Ele permite leituras opcionais do secundário, mas não gravações. Portanto, se o primário cair, você não poderá escrever até que o secundário se torne primário novamente. É assim que você sacrifica a alta disponibilidade no teorema CAP. Ao manter suas leituras apenas do primário, você pode ter uma consistência forte.

sn.anurag
fonte
2

O MongoDB seleciona Consistência em vez de Disponibilidade sempre que houver uma partição. O que significa é que quando há uma partição (P), ela escolhe Consistência (C) em vez de Disponibilidade (A).

Para entender isso, vamos entender como o MongoDB faz o conjunto de réplicas funciona. Um conjunto de réplicas possui um único nó primário. A única maneira "segura" de confirmar os dados é gravar naquele nó e, em seguida, esperar que os dados sejam confirmados para a maioria dos nós do conjunto. (você verá esse sinalizador para w = maioria ao enviar gravações)

A partição pode ocorrer em dois cenários da seguinte forma:

  • Quando o nó primário é desativado: o sistema fica indisponível até que um novo primário seja selecionado.
  • Quando o nó primário perde a conexão de muitos nós secundários: o sistema fica indisponível. Outros secundários tentarão eleger um novo primário e o primário atual deixará o cargo.

Basicamente, sempre que ocorre uma partição e o MongoDB precisa decidir o que fazer, ele escolherá Consistência em vez de Disponibilidade. Ele parará de aceitar gravações no sistema até acreditar que pode concluir essas gravações com segurança.

Rajneesh Prakash
fonte
“Ele vai parar de aceitar gravações no sistema até acreditar que pode concluir essas gravações com segurança. ” E as leituras ? Ele permaneceria disponível para leitura durante esse tempo?
Josh
1

O Mongodb fornece consistência e tolerância de partição .

No contexto de bancos de dados distribuídos (NoSQL), isso significa que sempre haverá uma compensação entre consistência e disponibilidade. Isso ocorre porque os sistemas distribuídos são sempre necessariamente tolerantes à partição (ou seja, simplesmente não seria um banco de dados distribuído se não fosse tolerante à partição).

Consistência - O sistema acabará por se tornar consistente. Os dados irão se propagar para todos os lugares que deveriam, mais cedo ou mais tarde, mas o sistema continuará a receber informações e não verificará a consistência de todas as transações antes de passar para a próxima.

Disponibilidade - Por padrão, o Mongo DB Client (driver MongoDB) envia todas as solicitações de leitura / gravação para o nó líder / primário. Isso torna o sistema consistente, mas não disponível devido a - Se um líder se desconectar do cluster, leva alguns segundos para eleger um novo líder. Portanto, tornando-o indisponível para gravações e leituras nessa duração.

Satakshi Pandey
fonte