mongodb, réplicas y error: {"$ err": "no maestro y esclavo Ok = falso", "código": 13435}

174

Probé los conjuntos de réplicas mongo por primera vez.

Estoy usando ubuntu en ec2 y arranqué tres instancias. Usé la dirección IP privada de cada una de las instancias. Elegí como principal y debajo está el código.

mongo --host Private IP Address
rs.initiate()
rs.add(“Private IP Address”)
rs.addArb(“Private IP Address”)

Todo en este punto está bien. Cuando voy al http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:28017/_replSet sitio, veo que tengo un primario, un segundo día y un árbitro.

Ok, ahora para una prueba.

En el primario crea una base de datos en este es el código:

use tt
db.tt.save( { a : 123 } )

en el secundario, luego hago esto y obtengo el siguiente error:

db.tt.find()
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }

Soy muy nuevo en mongodb y las réplicas, pero pensé que si hago algo en uno, va al otro. Entonces, si agrego un registro en uno, ¿qué debo hacer para replicar en las máquinas?

eLRuLL
fuente
descubrí que tengo que usar rs.slaveOk (); Eso me deja a otra pregunta. Tengo que hacer esto hacer esto para cada consulta? ¿Qué pasa si estoy en el nodo maestro?

Respuestas:

282

Debe establecer el modo "esclavo bien" para que el shell mongo sepa que está permitiendo lecturas de un secundario. Esto es para protegerlo a usted y a sus aplicaciones de realizar eventualmente lecturas consistentes por accidente. Puede hacer esto en el shell con:

rs.slaveOk()

Después de eso, puede consultar normalmente desde secundarias.

Una nota sobre la "coherencia eventual": en circunstancias normales, las secundarias del conjunto de réplicas tienen los mismos datos que las primarias en un segundo o menos. Bajo una carga muy alta, los datos que ha escrito en el primario pueden tardar un tiempo en replicarse en los secundarios. Esto se conoce como "retraso de réplica", y la lectura de un secundario rezagado se conoce como lectura "eventualmente consistente", porque, si bien los datos recién escritos se mostrarán en algún momento (salvo fallas en la red, etc.), puede que no sea Inmediatamente disponible.

Editar: solo necesita establecer slaveok cuando realiza consultas desde secundarias, y solo una vez por sesión.

dcrosta
fuente
3
Siempre consulte el manual antes de ejecutar comandos que no comprende en sus bases de datos. Podría haber consecuencias en el comando que la respuesta no explica. ¿Este comando cambia la forma en que se distribuyen las operaciones de lectura para todas las conexiones al conjunto de réplicas? Mejor averígualo. Este comando aparece ya en v2.2 docs.mongodb.com/v2.2/reference/method/rs.slaveOk Puede (y debe) reemplazar siempre la parte "/ manual /" de una URL de docs.mongodb.com a su versión específica para asegurarse de obtener información relevante.
Bruno Bronosky
45

Para evitar escribir rs.slaveOk()todo el tiempo, haga esto:

Cree un archivo llamado replStart.js, que contenga una línea:rs.slaveOk()

Luego incluya --shell replStart.jscuando inicie el shell Mongo. Por supuesto, si te estás conectando localmente a una sola instancia, esto no guarda ningún tipo de escritura.

Ed Norris
fuente
26
Una mejor manera de ahorrar en escribir sería agregar rs.slaveOk()a su ~/.mongorc.jsarchivo, que se ejecutará automáticamente al iniciar el shell mongo.
Stennie
2
Me parece útil para poner la configuración por defecto en ~/.mongorc.jsy configuraciones personalizadas en replStart.jso adminStart.jslo que sea.
Ed Norris
41

en mongodb2.0

deberías escribir

rs.slaveOk()

en el nodo secundario mongod

andyshi
fuente
11

ESTO ES SOLO UNA NOTA PARA CUALQUIER PERSONA QUE SE TRATA DE ESTE PROBLEMA USANDO EL CONDUCTOR RUBY

Tuve el mismo problema al usar Ruby Gem.

Para configurar slaveOk en Ruby, simplemente lo pasa como argumento cuando crea el cliente de esta manera:

mongo_client = MongoClient.new("localhost", 27017, { slave_ok: true })

https://github.com/mongodb/mongo-ruby-driver/wiki/Tutorial#making-a-connection

mongo_client = MongoClient.new # (optional host/port args)

Tenga en cuenta que 'args' es el tercer argumento opcional.

campeterson
fuente
1

Solo estoy agregando esta respuesta para una situación incómoda del proveedor de DB.

lo que sucedió en nuestro caso es que el db primario y secundario se movió inversamente (primario a secundario y viceversa) y estamos obteniendo el mismo error.

así que compruebe los ajustes de configuración para el estado de la base de datos que pueden ayudarlo.

jit
fuente
0

Llegué aquí buscando el mismo error, pero a partir de Node.js controlador nativo . La respuesta para mí fue la combinación de respuestas de campeterson y Prabhat .

El problema es que la readPreferenceconfiguración predeterminada es primary, que de alguna manera conduce al slaveOkerror confuso . Mi problema es que solo quiero leer mi conjunto de réplicas desde cualquier nodo. Ni siquiera me conecto a él como conjunto de réplicas. Solo me conecto a cualquier nodo para leerlo.

Establecer readPreferenceen primaryPreferred(o mejor a la ReadPreference.PRIMARY_PREFERREDconstante) lo resolvió para mí. Simplemente páselo como una opción MongoClient.connect()ao para client.db()o para cualquier find(), aggregate()u otra función.

const { MongoClient, ReadPreference } = require('mongodb');
const client = await MongoClient.connect(MONGODB_CONNECTIONSTRING, { readPreference: ReadPreference.PRIMARY_PREFERRED });
kub1x
fuente