Overview
En esta guía, puedes aprender cómo configurar las opciones de nivel de confirmación de escritura (write concern), nivel de consistencia de lectura y preferencia de lectura para modificar la manera en que el driver Java Reactive Streams ejecutar operación de lectura y escritura en set de réplicas.
Prioridad de configuración de lectura y guardado
Puedes establecer las opciones de nivel de confirmación de escritura (write concern), nivel de consistencia de lectura y preferencia de lectura en los siguientes niveles:
Cliente, que establece el por defecto para todas las ejecuciones de operaciones, a menos que se anule
transacción
Database
Colección
Esta lista también indica el orden creciente de prioridad de las configuraciones de opciones. Por ejemplo, si se establece un nivel de consistencia de lectura para una transacción, se anularán las configuraciones de nivel de consistencia de lectura heredadas del cliente.
Las opciones de nivel de confirmación de escritura (write concern), nivel de consistencia de lectura y preferencia de lectura permiten personalizar la coherencia causal y la disponibilidad de los datos en tus sets de réplicas. Para ver una lista completa de estas opciones, consulte las siguientes guías en el manual de MongoDB Server:
Configurar operaciones de lectura y guardar
Se puede controlar cómo el driver enruta las operaciones de lectura entre los miembros del set de réplicas estableciendo una preferencia de lectura. También puedes controlar cómo el driver espera el reconocimiento de las operaciones de lectura y nivel de confirmación de escritura (write concern) en un set de réplicas configurando los concerns de lectura y nivel de confirmación de escritura (write concern).
Las siguientes secciones muestran cómo configurar estos parámetros de lectura y guardado en varios niveles.
Configuración del cliente
Este ejemplo muestra cómo establecer la preferencia de lectura, el nivel de consistencia de lectura y el nivel de confirmación de escritura (write concern) de una instancia de MongoClient pasando una instancia de MongoClientSettings al método MongoClients.create(). El código configura los siguientes ajustes:
secondarypreferencia de lectura: las operaciones de lectura recuperan datos de miembros secundarios del set de réplicas.LOCALNivel de consistencia de lectura: las operaciones de lectura devuelven los datos más recientes de la instancia sin garantizar que los datos hayan sido escritos en la mayoría de los miembros del grupo de réplicas.W2nivel de confirmación de escritura (write concern): El primario del set de réplicas y un secundario deben reconocer la operación de grabación.
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);
Como alternativa, puede especificar los ajustes de lectura y escritura en el URI de conexión, que se pasa como un parámetro al método MongoClients.create():
MongoClient client = MongoClients.create( "mongodb://<host>:<port>/?readPreference=secondary&readConcernLevel=local&w=2");
Configuración de transacciones
Este ejemplo muestra cómo configurar la preferencia de lectura, la preocupación de lectura y el nivel de confirmación de escritura (write concern) de una transacción al pasar una instancia TransactionOptions al método startTransaction(). Las transacciones se ejecutan en sesiones, que son agrupaciones de operaciones de lectura o guardar relacionadas que se desean ejecutar de forma secuencial. Antes de aplicar las opciones de transacción, utiliza el método startSession() para iniciar una sesión.
Tip
Para obtener más información sobre las sesiones, consulte Sesiones del Servidor en el manual del MongoDB Server.
El ejemplo configura los siguientes ajustes:
primarypreferencia de lectura: Las operaciones de lectura recuperan los datos del miembro primario del set de réplicas.MAJORITYnivel de consistencia de lectura: Las operaciones de lectura devuelven los datos más recientes de la instancia que se han escrito en la mayoría de los miembros del set de réplicas.W1nivel de confirmación de escritura (write concern): El miembro primario del conjunto de réplicas debe acuse de recibo de la operación de escritura.
ClientSession clientSession = Mono.from(client.startSession()).block(); TransactionOptions txnOptions = TransactionOptions.builder() .readPreference(ReadPreference.primary()) .readConcern(ReadConcern.MAJORITY) .writeConcern(WriteConcern.W1) .build(); clientSession.startTransaction(txnOptions);
Configuración de la base de datos
Este ejemplo muestra cómo configurar la preferencia de lectura, el nivel de consistencia de lectura y el nivel de confirmación de escritura (write concern) de una base de datos llamada test_database encadenando métodos 'setter' al método getDatabase(). El código configura los siguientes ajustes:
primaryPreferredpreferencia de lectura: las operaciones de lectura recuperan datos del miembro primario del set de réplicas o de miembros secundarios si el primario no está disponible.AVAILABLENivel de consistencia de lectura: las operaciones de lectura devuelven los datos más recientes de la instancia sin garantizar que los datos hayan sido escritos en la mayoría de los miembros del grupo de réplicas.MAJORITYnivel de confirmación de escritura (write concern): La mayoría de todos los miembros del set de réplicas deben reconocer la operación de escritura.
MongoDatabase database = client.getDatabase("test_database") .withReadPreference(ReadPreference.primaryPreferred()) .withReadConcern(ReadConcern.AVAILABLE) .withWriteConcern(WriteConcern.MAJORITY);
Nota
Las bases de datos y las colecciones son inmutables
MongoDatabase y las instancias MongoCollection son inmutables. Cuando se establece la preferencia de lectura, el nivel de consistencia de lectura o el nivel de confirmación de escritura (write concern) en una base de datos o colección, el método devuelve una nueva instancia y no afecta a la instancia original.
Configuración de la colección
Este ejemplo muestra cómo configurar la preferencia de lectura, el nivel de consistencia de lectura y el nivel de confirmación de escritura (write concern) de una colección llamada test_collection, encadenando métodos setters al método getCollection(). El código configura la siguiente configuración:
secondaryPreferredpreferencia de lectura: Las operaciones de lectura recuperan datos de los nodos secundarios del set de réplicas, o del nodo primario si no se dispone de nodos secundarios.AVAILABLENivel de consistencia de lectura: las operaciones de lectura devuelven los datos más recientes de la instancia sin garantizar que los datos hayan sido escritos en la mayoría de los miembros del grupo de réplicas.UNACKNOWLEDGEDnivel de confirmación de escritura (write concern): Los miembros del conjunto de réplicas no necesitan reconocer la operación de escritura.
MongoCollection<Document> collection = database.getCollection("test_collection") .withReadPreference(ReadPreference.secondaryPreferred()) .withReadConcern(ReadConcern.AVAILABLE) .withWriteConcern(WriteConcern.UNACKNOWLEDGED);
Configuraciones avanzadas de lectura
Las siguientes secciones describen formas de personalizar aún más cómo el controlador Java Reactive Streams enruta las operaciones de lectura.
Clústeres fragmentados
Se puede especificar una preferencia de lectura cuando se conecta a un clúster fragmentado. MongoDB utiliza particionado para dividir conjuntos de datos por rangos de claves y distribuir datos entre varias instancias de bases de datos. Un clúster particionado, o el conjunto de nodos en una implementación particionada, incluye los siguientes componentes:
Partición: Un set de réplicas que contiene un subconjunto de los datos particionados
mongos: Un enrutador de query que proporciona una interfaz entre la aplicación y el clúster particionado
Servidores de configuración: servidores que almacenan la configuración y los metadatos del clúster
Tip
Para obtener más información sobre los clústeres compartimentados, consulte Particionado en el manual de MongoDB Server.
Al leer de las particiones del set de réplicas, mongos aplica su preferencia de lectura especificada. La preferencia de lectura se reevalúa para cada operación.
El siguiente ejemplo muestra cómo conectarse a un clúster fragmentado y especificar una preferencia de lectura secondary en tu cadena de conexión:
MongoClient client = MongoClients.create( "mongodb://<host>:<port>/?readPreference=secondary");
Conjuntos de etiquetas
En MongoDB Server, puedes aplicar etiquetas de clave-valor a los miembros del set de réplicas según cualquier criterio que elijas. A continuación, puedes usar esas etiquetas para dirigir una operación de lectura a uno o más nodos.
Por defecto, el driver de Java Reactive Streams ignora las etiquetas al elegir un nodo del que leer. Para indicar al driver de Java Reactive Streams que prefiera ciertas etiquetas, pase las etiquetas como una lista al método configurador de preferencia de lectura.
Supongamos que está conectado a un set de réplicas que contiene nodos alojados en múltiples centros de datos en todo Estados Unidos. Desea que el driver prefiera las lecturas de los miembros secundarios del set de réplicas en el siguiente orden:
Miembros del centro de datos de Nueva York, etiquetados con
("dc", "ny")Nodos del centro de datos de San Francisco, etiquetados con
("dc", "sf")Cualquier miembro secundario
Este ejemplo de código pasa una lista de etiquetas que representan a los miembros anteriores del set de réplicas al método setter ReadPreference.secondary(). Luego, el código pasa la información de preferencia de lectura al método withReadPreference() para establecer el orden de lectura en la base de datos:
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));
Equilibrio de carga
Al conectarse a un clúster particionado o a un set de réplicas, el driver de Java Reactive Streams utiliza el balanceo de carga para gestionar las solicitudes de lectura y escritura. El balanceo de carga permite que el driver distribuya estas solicitudes entre varios servidores, lo que evita sobrecargar cualquier servidor y garantiza un rendimiento óptimo.
Al conectarse a un clúster particionado, el driver Java Reactive Streams determina la instancia mongos más cercana calculando cuál tiene el tiempo de ida y vuelta de red más bajo. Luego, el driver determina la ventana de latencia agregando el tiempo de ida y vuelta promedio de esta instancia mongos al valor localThresholdMS. El driver equilibra la carga de las solicitudes en hasta dos instancias mongos aleatorias que se encuentran dentro de la ventana de latencia. Para cada solicitud, el driver elige el servidor con la carga de operación más baja determinando su valor operationCount.
Al conectarse a un set de réplicas, el driver de Java Reactive Streams selecciona primero los nodos del set de réplicas según su preferencia de lectura. Luego, el driver sigue el mismo proceso descrito en el párrafo anterior. Después de calcular la ventana de latencia, el driver selecciona hasta dos nodos de set de réplicas aleatorios que se encuentran dentro de la ventana y elige el nodo con el valor operationCount más bajo para recibir la solicitud.
Tip
Para obtener más información sobre el balanceo de carga, consulte Balanceador de clúster en el manual de MongoDB Server.
Umbral local
El driver Java Reactive Streams utiliza el valor de umbral local para calcular la ventana de latencia para la selección del servidor. Este valor determina los servidores que pueden recibir solicitudes de lectura y guardar.
De forma predeterminada, el driver utiliza únicamente mongos instancias o miembros del set de réplicas cuyos tiempos de ping están dentro de 15 milisegundos del servidor más cercano. Para distribuir las lecturas entre servidores con mayores latencias, configure la opción localThreshold en una instancia MongoClientSettings o la opción localThresholdMS en su URI de conexión.
Nota
Al seleccionar set de réplicas de una sola instancia mongos, el driver Java Reactive Streams ignora la opción localThresholdMS. En este caso, utilice la opción de línea de comandos mongos --localThreshold.
El siguiente ejemplo se conecta a un set de réplicas y especifica un umbral local de 35 milisegundos. Selecciona la pestaña MongoClientSettings o Connection URI para ver el código correspondiente de cada enfoque:
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");
En el ejemplo anterior, el driver de Java Reactive Streams distribuye las lecturas entre los nodos correspondientes dentro de 35 milisegundos del tiempo de ping del nodo más cercano.
Lecturas y Guardados Reintentarles
El driver de Java Reactive Streams reintenta automáticamente algunas operaciones de lectura y guardado una sola vez si fallan debido a un error de red o del servidor.
Puedes desactivar explícitamente las lecturas o la escritura reintentable estableciendo la opción retryReads o retryWrites en false en una instancia MongoClientSettings. También puede establecer las opciones retryReads o retryWrites en el URI de su conexión.
El siguiente ejemplo establece tanto las lecturas como las escrituras reintentables en false. Selecciona la pestaña MongoClientSettings o Connection URI para ver el código correspondiente a cada enfoque:
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 obtener más información sobre las operaciones de lectura repetibles admitidas, consulte Lecturas repetibles en el manual de MongoDB Server. Para obtener más información sobre las operaciones de escritura reintentables admitidas, consulta Escrituras reintentables en el manual del MongoDB Server.
Documentación de la API
Para aprender más sobre cualquiera de los métodos o tipos analizados en esta guía, consulta la siguiente documentación de API: