Definir preocupações globais de leitura e gravação no MongoDB 4.4
Avalie esse Artigo
MongoDB é muito flexível quando se trata de leitura e gravação de dados. Quando se trata de gravar dados, uma preocupação de gravaçãodo MongoDB permite que você defina o nível de confirmação para uma operação de gravação desejada. Da mesma forma, a preocupação de leitura permite controlar as propriedades de consistência e isolamento dos dados lidos de seus conjuntos de réplicas. Encontrar os valores corretos para as preocupações de leitura e gravação é fundamental à medida que seu aplicativo evolui e, com a versão mais recente do MongoDB, agora é possível adicionar padrões globais de isolamento de leitura e durabilidade de gravação.
MongoDB 4.4 está disponível em versão beta no momento. Você pode testá-lo no MongoDB Atlas ou baixar a versão de desenvolvimento. Neste post, vamos ver como podemos definir nossos padrões de isolamento de leitura e durabilidade de escrita globalmente e também como podemos substituir essas configurações globais por cliente ou por operação, quando necessário.
Para este tutorial, você precisará de:
A definição de write and read writes não está disponível no momento no MongoDB Atlas. Para acompanhar este tutorial, você precisará de sua própria instância do MongoDB 4.4 instalado.
Antes de falarmos sobre como podemos definir esses recursos globalmente, vamos examinar rapidamente o que eles realmente fazem, quais benefícios eles oferecem e por que devemos nos importar.
Começaremos com a funcionalidade de preocupação de gravação do MongoDB . Por padrão, quando você envia uma operação de gravação para um MongoDB database, ela tem uma preocupação de gravação de
w:1
. Isso significa que a operação de gravação será reconhecida como bem-sucedida quando o primário em um conjunto de réplicas tiver executado com êxito a operação de gravação .Suponhamos que você esteja trabalhando com um conjunto de replicação 3nós, que é o padrão ao criar um cluster MongoDB Atlas gratuito.O envio de um comando de gravação, como
db.collection('test').insertOne({name:"Ado"})
, será considerado bem-sucedido quando o primário confirmar a gravação. Isso garante que os dados não violem nenhuma restrição do banco de dados e tenham sido gravados com êxito no banco de dados na memória. Podemos melhorar a durabilidade dessa preocupação de gravação, aumentando o número de nós que queremos reconhecer a gravação.Em vez de
w:1
, digamos que o definimos como w:2
. Agora, quando enviamos uma operação de gravação para o banco de dados, não receberíamos uma resposta até que o nó primário e um dos dois nós secundários reconhecessem que a operação de gravação foi bem-sucedida. Da mesma forma, também poderíamos definir o valor de confirmação como 0, ou seja, w:0
, e, neste caso, não pediríamos nenhuma confirmação. Eu não recomendaria usar w:0
para dados importantes, mas em alguns casos pode ser uma opção válida. Finalmente, se tivéssemos um conjunto de réplicas de três membros e definirmos o valor w como 3, ou seja, w:3
, agora o nó primário e ambos os nós secundários precisariam reconhecer a gravação. Eu também não recomendaria essa abordagem, porque se um dos membros secundários ficar indisponível, não poderemos reconhecer as operações de gravação e nosso sistema não estará mais altamente disponível.Além disso, quando se trata de write concern, não estamos limitados a definir um valor numérico. Podemos definir o valor de w como "maioria", por exemplo, que aguardará que a operação de gravação se propague para a maioria dos nós ou até mesmo escrever nossa própria write concern personalizada.
A preocupação com leitura do MongoDB permite que você controle as propriedades de consistência e isolamento dos dados lidos de conjuntos de réplicas e fragmentos de conjuntos de réplicas. Esseticamente, o que isso significa é que, quando você envia uma operação de leitura para o banco de dados, como um db.collection.find(), pode especificar a durabilidade dos dados retornados. Observe que a read concern não deve ser confundida com a read preference, que especifica de qual membro de um conjunto de réplicas você deseja ler.
Existem vários níveis de read concern, incluindo local, disponível, majoritário, linearizávele instantâneo. Cada nível é complexo o suficiente para que possa ser um artigo em si, mas a ideia geral é semelhante à da write concern. Definir um nível de read concern permitirá que você controle o tipo de leitura de dados. Os padrões para read concerns podem variar e você pode descobrir qual padrão é aplicado aqui. A read concern padrão lê os dados mais recentes, em vez de dados que foram confirmados por maioria.
Por meio do uso efetivo de write concerns e read concerns, você pode ajustar o nível de padrões de consistência e disponibilidade conforme apropriado para seu aplicativo.
Agora que sabemos um pouco mais sobre por que esses recursos existem e como funcionam, vejamos como podemos alterar os padrões globalmente. No MongoDB 4.4, podemos usar o db.adminCommand() para configurar nossos padrões de isolamento e durabilidade.
A definição de write and read writes não está disponível no momento no MongoDB Atlas. Para acompanhar este tutorial, você precisará de sua própria instância do MongoDB 4.4 instalado.
Usaremos o
db.adminCommand()
para definir uma read e write concern padrão. Na shell MongoDB, execute o seguinte comando:1 db.adminCommand({ 2 setDefaultRWConcern: 1, 3 defaultReadConcern: { level : "majority" }, 4 defaultWriteConcern: { w: "majority" } 5 })
Observe que, para executar esse comando, você precisa ter uma réplica definida e o comando precisará ser enviado ao nó primário. Além disso, se você tiver um cluster fragmentado, o comando precisará ser executado no
mongos
. Se você tiver um nó independente, receberá um erro. O requisito final para poder executar o comandosetDefaultRWConcern
é ter o privilégio correto.Ao definir preocupações de leitura e gravação padrão, você não precisa definir uma preocupação de leitura padrão e uma preocupação de gravação padrão, você tem permissão para definir apenas uma preocupação de leitura padrão ou uma preocupação de gravação padrão conforme achar adequado. Por exemplo, digamos que só queremos definir uma write concern padrão, seria algo assim:
1 db.adminCommand({ 2 setDefaultRWConcern: 1, 3 defaultWriteConcern: { w: 2 } 4 })
O comando acima definiria apenas uma write concern padrão de 2, o que significa que a escrita seria bem-sucedida quando o nó primário e um secundário confirmassem a escrita.
Quando se trata de write concerns padrão, além de especificar a confirmação, você também pode definir um período
wtimeout
para quanto tempo uma operação deve aguardar uma confirmação. Para definir isso, podemos fazer isso:1 db.adminCommand({ 2 setDefaultRWConcern: 1, 3 defaultWriteConcern: { w: 2, wtimeout: 5000 } 4 })
Isso definirá um tempo limite de 5000ms; portanto, se não recebermos uma confirmação dentro 5 segundos, a operação de gravação retornará um erro de tempo limite
writeConcern
.Para desconfigurar uma read ou write concern padrão, você pode simplesmente passar para ela um objeto vazio.
1 db.adminCommand({ 2 setDefaultRWConcern: 1, 3 defaultReadConcern: { }, 4 defaultWriteConcern: { } 5 })
Isso retornará a preocupação de leitura e a preocupação de gravação para seus padrões MongoDB. Você também pode verificar e ver facilmente quais padrões estão definidos atualmente para suas preocupações globais de leitura e escrita usando o comando getDefaultRWConcern. Quando você executa este comando no banco de dados do
admin
da seguinte forma:1 db.adminCommand({ 2 getDefaultRWConcern: 1 3 })
Você receberá uma resposta como a que está abaixo, mostrando suas configurações globais:
1 { 2 "defaultWriteConcern" : { 3 "w" : "majority" 4 }, 5 "defaultReadConcern" : { 6 "level" : "majority" 7 }, 8 "updateOpTime" : Timestamp(1586290895, 1), 9 "updateWallClockTime" : ISODate("2020-04-07T20:21:41.849Z"), 10 "localUpdateWallClockTime" : ISODate("2020-04-07T20:21:41.862Z"), 11 "ok" : 1, 12 "$clusterTime" : { ... } 13 "operationTime" : Timestamp(1586290925, 1) 14 }
Na próxima seção, veremos como podemos substituir essas configurações globais quando necessário.
O MongoDB é um banco de dados muito flexível. As preocupações padrão de leitura e gravação permitem que você defina padrões razoáveis para como os clientes interagem com seu banco de dados em todo o cluster, mas à medida que seu aplicativo evolui, um cliente específico pode precisar de um isolamento de leitura diferente ou padrão de durabilidade de gravação. Isso pode ser feito usando qualquer um dos drivers do MongoDB.
Podemos substituir as preocupações de leitura e escrita em:
- a camada de conexão do cliente ao conectar ao MongoDB database,
- O nível de banco de dados,
- O nível da coleção,
- uma operação ou query individual.
No entanto, observe que astransações do MongoDB podem abranger vários bancos de dados e collections e, como todas as operações em uma transação devem usar a mesma write concern, as transações têm sua própria hierarquia de:
- camada de conexão do cliente,
- nível da sessão,
- o nível de transação.
Um diagrama mostrando essa herança é apresentado abaixo para ajudá-lo a entender qual read e write concern tem precedência quando múltiplas são declaradas:
Veremos alguns exemplos em que substituímos as preocupações de leitura e escrita. Para nossos exemplos, usaremos o Driver Node.js.
Vamos ver um exemplo de como substituiríamos nossas preocupações de leitura e gravação em nosso aplicativo Node.js. O primeiro exemplo que veremos é como substituir as questões de leitura e gravação no nível do banco de dados. Para fazer isso, nosso código ficará assim:
1 const MongoClient = require('mongodb').MongoClient; 2 const uri = "{YOUR-CONNECTION-STRING}"; 3 const client = new MongoClient(uri, { useNewUrlParser: true }); 4 5 client.connect(err => { 6 const options = {w:"majority", readConcern: {level: "majority"}}; 7 8 const db = client.db("test", options); 9 });
Quando especificamos o banco de dados ao qual queremos nos conectar, neste caso o banco de dados é chamado
test
, também passamos um objetooptions
com as preocupações de leitura e escrita que desejamos usar. Para nosso primeiro exemplo, estamos usando a preocupaçãomajoritária para operações de leitura e gravação.Se já estivermos definindo padrões globalmente, a substituição dessa forma pode não fazer sentido, mas ainda podemos nos deparar com uma situação em que queremos que uma collectionespecífica execute operações de leitura e escrita em um read ou write concern específico. Vamos declarar uma collection com uma write concernmajoritária e uma read concern "maioria".
1 const options = {w:"majority", readConcern: {level: "majority"}}; 2 3 const collection = db.collection('documents', options);
Da mesma forma, podemos até mesmo fazer o escopo para uma operação específica. No exemplo a seguir, usaremos a maioriadas preocupações de leitura para apenas uma query específica.
1 const collection = db.collection('documents'); 2 3 collection.insertOne({name:"Ado Kukic"}, {w:"majority", wtimeout: 5000})
O código acima executará uma consulta de gravação e tentará inserir um documento que tenha um campo intitulado nome. Para que a consulta seja bem-sucedida, a operação de gravação deverá ser reconhecida pelo primário e por um secundário, supondo que tenhamos um conjunto de réplicas de três membros.
Ser capaz de definir as questões padrão de leitura e gravação é importante para fornecer aos desenvolvedores a capacidade de definir padrões que façam sentido para seu caso de uso, mas também a flexibilidade de substituir esses padrões facilmente quando necessário.
As preocupações globais de leitura ou gravação permitem que os desenvolvedores definam o isolamento de leitura padrão e os padrões de durabilidade de gravação para todo o cluster de banco de dados. À medida que seu aplicativo evolui, você pode substituir as preocupações globais de leitura e gravação no nível do cliente, garantindo flexibilidade quando precisar e padrões personalizados quando não precisar. Está disponível no MongoDB 4.4, que está disponível em versão beta hoje.
Declaração de Porto Seguro
O desenvolvimento, lançamento e cronograma de quaisquer recursos ou funcionalidades descritos para produtos MongoDB permanecem a critério exclusivo da MongoDB. Esta informação destina-se apenas a delinear a direção geral do nosso produto e não deve ser invocada na tomada de uma decisão de compra nem é um compromisso, promessa ou obrigação legal de entregar qualquer material, código ou funcionalidade. Exceto conforme exigido por lei, não assumimos nenhuma obrigação de atualizar quaisquer declarações prospectivas para refletir eventos ou circunstâncias após a data de tais declarações.