Visão geral
Neste guia, você pode aprender como configurar as opções de write concern, read concern e preferência de leitura para modificar a maneira como o driver Java Reactive Streams executa operações de leitura e escrita em conjuntos de réplicas.
Precedência de configurações de leitura e gravação
É possível definir as opções de preocupação de gravação, preocupação de leitura e preferência de leitura nos seguintes níveis:
Cliente, que define o padrão para todas as execuções de operações, a menos que seja substituído
transação
Database
collection
Esta lista também indica a ordem crescente de precedência das configurações de opção. Por exemplo, se você definir uma preocupação de leitura para uma transação, ela substituirá as configurações de preocupação de leitura herdadas do cliente.
As opções de write concern, preocupação de leitura e preferência de leitura permitem personalizar a consistência causal e a disponibilidade dos dados em seus conjuntos de réplicas. Para ver uma lista completa dessas opções, consulte os seguintes guias no manual do MongoDB Server :
Configurar operações de leitura e escrita
Você pode controlar como o driver roteia as operações de leitura entre os membros do conjunto de réplicas definindo uma preferência de leitura. Você também pode controlar como o driver aguarda a confirmação das operações de leitura e gravação em um conjunto de réplicas definindo preocupações de leitura e gravação.
As seções a seguir mostram como definir essas configurações de leitura e gravação em vários níveis.
Configuração do cliente
Esse exemplo mostra como definir a preferência de leitura, preocupação de leitura e preocupação de gravação de uma instância MongoClient passando uma instância MongoClientSettings para o método MongoClients.create(). O código define as seguintes configurações:
secondarypreferência de leitura: as operações de leitura recuperam dados de nós secundários do conjunto de réplicas.LOCALpreocupação de leitura: as operações de leitura retornam os dados mais recentes da instância sem garantir que os dados tenham sido gravados na maioria dos membros do conjunto de réplicas.W2preocupação de gravação: o membro primário do conjunto de réplicas e um membro secundário devem confirmar a operação de gravação.
MongoClientSettings settings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString("<your connection string>")) .readPreference(ReadPreference.secondary()) .readConcern(ReadConcern.LOCAL) .writeConcern(WriteConcern.W2) .build(); MongoClient client = MongoClients.create(settings);
Alternativamente, você pode especificar as configurações de leitura e escrita no URI de conexão, que é passado como um parâmetro para o método MongoClients.create():
MongoClient client = MongoClients.create( "mongodb://<host>:<port>/?readPreference=secondary&readConcernLevel=local&w=2");
Configuração da transação
Este exemplo mostra como definir a preferência de leitura, preocupação de leitura e preocupação de gravação de uma transação passando uma instância TransactionOptions para o método startTransaction(). As transações são executadas dentro de sessões, que são agrupamentos de operações de leitura ou escrita relacionadas que você pretende executar sequencialmente. Antes de aplicar as opções de transação, utilize o método startSession() para iniciar uma sessão.
Dica
Para saber mais sobre sessões, consulte Sessões do servidor no manual do MongoDB Server .
O exemplo define as seguintes configurações:
primarypreferência de leitura: as operações de leitura recuperam dados do membro primário do conjunto de réplicas.MAJORITYpreocupação de leitura: as operações de leitura retornam os dados mais recentes da instância que foram gravados para a maioria dos membros do conjunto de réplicas.W1preocupação de gravação: o membro primário do conjunto de réplicas deve confirmar a operação de gravação.
ClientSession clientSession = Mono.from(client.startSession()).block(); TransactionOptions txnOptions = TransactionOptions.builder() .readPreference(ReadPreference.primary()) .readConcern(ReadConcern.MAJORITY) .writeConcern(WriteConcern.W1) .build(); clientSession.startTransaction(txnOptions);
Configuração do Banco de Dados
Este exemplo mostra como definir a preferência de leitura, preocupação de leitura e preocupação de gravação de um banco de dados chamado test_database encadeando métodos de configuração ao método getDatabase(). O código define as seguintes configurações:
primaryPreferredpreferência de leitura: as operações de leitura recuperam dados do membro primário do conjunto de réplicas ou de membros secundários se o principal não estiver disponível.AVAILABLEpreocupação de leitura: as operações de leitura retornam os dados mais recentes da instância sem garantir que os dados tenham sido gravados na maioria dos membros do conjunto de réplicas.MAJORITYpreocupação de gravação: A maioria de todos os membros do conjunto de réplicas deve reconhecer a operação de escrita.
MongoDatabase database = client.getDatabase("test_database") .withReadPreference(ReadPreference.primaryPreferred()) .withReadConcern(ReadConcern.AVAILABLE) .withWriteConcern(WriteConcern.MAJORITY);
Observação
Bancos de dados e coleções são imutáveis
MongoDatabase e MongoCollection instâncias são imutáveis. Quando você define a preferência de leitura, read concern ou write concern em um banco de dados ou coleção, o método retorna uma nova instância e não afeta a instância original.
Configuração da Coleção
Este exemplo mostra como definir a preferência de leitura, preocupação de leitura e preocupação de gravação de uma collection chamada test_collection encadeando métodos setter ao método getCollection() . O código define as seguintes configurações:
secondaryPreferredpreferência de leitura: as operações de leitura recuperam dados de nós secundários do conjunto de réplicas ou do nó primário se nenhum nó secundário estiver disponível.AVAILABLEpreocupação de leitura: as operações de leitura retornam os dados mais recentes da instância sem garantir que os dados tenham sido gravados na maioria dos membros do conjunto de réplicas.UNACKNOWLEDGEDpreocupação de gravação: os membros do conjunto de réplicas não precisam confirmar a operação de gravação.
MongoCollection<Document> collection = database.getCollection("test_collection") .withReadPreference(ReadPreference.secondaryPreferred()) .withReadConcern(ReadConcern.AVAILABLE) .withWriteConcern(WriteConcern.UNACKNOWLEDGED);
Configurações avançadas de leitura
As seções a seguir descrevem maneiras de personalizar ainda mais como o driver Java Reactive Streams direciona as operações de leitura.
Clusters fragmentados
Você pode especificar uma preferência de leitura ao se conectar a um cluster fragmentado. O MongoDB usa fragmentação para dividir conjuntos de dados por intervalos de chaves e distribuir dados em várias instâncias do banco de dados . Um cluster fragmentado, ou o conjunto de nós em um sistema fragmentado, inclui os seguintes componentes:
Shard: um conjunto de réplicas que contém um subconjunto dos dados sharded
mongos: um roteador de query que fornece uma interface entre seu aplicativo e o cluster sharded
servidor de configuração: servidor que armazena as definições de configuração e os metadados do cluster
Dica
Para saber mais sobre clusters sharded, consulte Sharding no manual do MongoDB Server.
Ao ler a partir dos shards do conjunto de réplicas, mongos aplica sua preferência de leitura especificada. A preferência de leitura é reavaliada para cada operação.
O exemplo a seguir mostra como se conectar a um cluster fragmentado e especificar uma preferência de leitura secondary em sua string de conexão:
MongoClient client = MongoClients.create( "mongodb://<host>:<port>/?readPreference=secondary");
Conjuntos de tags
No MongoDB Server, você pode aplicar tags de valor-chave a membros do conjunto de réplicas de acordo com qualquer critério que você escolher. Você pode então usar essas tags para direcionar um ou mais nós para uma operação de leitura.
Por padrão, o driver Java Reactive Streams ignora as tags ao escolher um nó para ler. Para instruir o driver de fluxos reativos Java a preferir determinadas tags, passe as tags como uma lista para seu método de configuração de preferência de leitura.
Suponha que você esteja conectado a um conjunto de réplicas que contém membros hospedados em vários data centers nos Estados Unidos. Você deseja que o driver prefira leituras de nós secundários do conjunto de réplicas na seguinte ordem:
Membros do centro de dados de Nova York, marcados com
("dc", "ny")Membros do centro de dados de São Francisco, marcados com
("dc", "sf")Quaisquer membros secundários
Este exemplo de código passa uma lista de tags que representam os membros do conjunto de réplicas anteriores para o método de configuração ReadPreference.secondary(). Em seguida, o código passa as informações de preferência de leitura para o método withReadPreference() para definir a ordem de leitura no banco de dados:
List<TagSet> tagSetList = Arrays.asList( new TagSet(new Tag("dc", "ny")), new TagSet(new Tag("dc", "sf")), new TagSet() ); MongoDatabase database = client.getDatabase("test_database") .withReadPreference(ReadPreference.secondary(tagSetList));
Balanceamento de carga
Ao se conectar a um cluster sharded ou a um conjunto de réplicas, o driver Java Reactive Streams usa o balanceamento de carga para lidar com as solicitações de leitura e gravação. O balanceamento de carga permite que o driver distribua essas solicitações em vários servidores, o que evita sobrecarregar qualquer servidor e garante o desempenho ideal.
Ao conectar-se a um cluster sharded, o driver Java Reactive Streams determina a instância mongos mais próxima calculando qual tem o menor tempo de ida e volta da rede. Em seguida, o driver determina a janela de latência adicionando o tempo médio de ida e volta desta instância mongos ao valor localThresholdMS. O driver balanceia a carga das solicitações em até duas instâncias mongos aleatórias que se enquadram na janela de latência. Para cada solicitação, o driver escolhe o servidor com a menor carga de operação determinando seu valor operationCount.
Ao conectar-se a um conjunto de réplicas, o driver Java Reactive Streams primeiro seleciona os nós do conjunto de réplicas de acordo com sua preferência de leitura. Em seguida, o driver segue o mesmo processo descrito no parágrafo anterior. Depois de calcular a janela de latência, o driver seleciona até dois nós de conjunto de réplicas aleatórios que se enquadram na janela e escolhe o nó com o valor operationCount mais baixo para receber a solicitação.
Dica
Para saber mais sobre balanceamento de carga, consulte Sharded Cluster Balancer no manual do MongoDB Server.
LocalThreshold
O driver Java Reactive Streams usa o valor de limite local para calcular a janela de latência para seleção do servidor. Esse valor determina os servidores que estão qualificados para receber solicitações de leitura e gravação.
Por padrão, o driver usa apenas mongos instâncias ou membros do conjunto de réplicas cujos tempos de ping estão dentro de 15 milissegundos do servidor mais próximo. Para distribuir leituras entre servidores com latências mais altas, defina a opção localThreshold em uma instância do MongoClientSettings ou a opção localThresholdMS no seu URI de conexão.
Observação
Ao selecionar nós de conjunto de réplicas de uma única instância mongos, o driver Java Reactive Streams ignora a opção localThresholdMS. Nesse caso, use a opção de linha de comando mongos --localThreshold.
O exemplo a seguir conecta a um conjunto de réplica e especifica um limite local de 35 milissegundos. Selecione a aba MongoClientSettings ou Connection URI para ver o código correspondente para cada abordagem:
MongoClientSettings settings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString("<your connection string>")) .applyToClusterSettings(builder -> builder.localThreshold(35, TimeUnit.MILLISECONDS)) .build(); MongoClient client = MongoClients.create(settings);
MongoClient client = MongoClients.create( "mongodb://<host>:<port>/?localThresholdMS=35");
No exemplo anterior, o driver Java Reactive Streams distribui leituras entre nós correspondentes dentro de 35 milissegundos do tempo de ping do nó mais próximo.
Leituras e gravações retráteis
O driver Java Reactive Streams tenta automaticamente determinadas operações de leitura e gravação uma única vez se elas falharem devido a um erro de rede ou servidor.
Você pode desabilitar explicitamente as leituras ou gravações repetíveis definindo a opção retryReads ou retryWrites como false em uma instância MongoClientSettings . Você também pode definir as opções retryReads ou retryWrites no URI de conexão.
O exemplo a seguir define leituras e gravações repetíveis como false. Selecione a aba MongoClientSettings ou Connection URI para ver o código correspondente para cada abordagem:
MongoClientSettings settings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString("<your connection string>")) .retryReads(false) .retryWrites(false) .build(); MongoClient client = MongoClients.create(settings);
MongoClient client = MongoClients.create( "mongodb://<host>:<port>/?retryReads=false&retryWrites=false");
Para saber mais sobre as operações de leitura repetível com suporte, consulte Leituras repetíveis no manual do MongoDB Server . Para saber mais sobre as operações de gravações repetíveis com suporte, consulte Retryable writes no manual do MongoDB Server .
Documentação da API
Para saber mais sobre qualquer um dos métodos ou tipos discutidos neste guia, consulte a seguinte documentação da API: