2012-04-04 9 views
7

Estoy tratando de usar mongodb como almacenamiento de configuración de red. Esta misma aplicación se ejecuta en varias máquinas en la red, cada una extrae su configuración de su mongodb local. Los mongodbs están sincronizados. Lo que me gustaría es obtener una devolución de llamada/notificación en todas las aplicaciones n-1 si una aplicación cambia cualquiera de los valores de configuración. ¿Es posible este tipo de configuración?Obtener notificación de documentos modificados en mongodb

(Sería salvarme de hacer la transferencia de la red/etc para sincronización mí mismo.)

Respuesta

9

MongoDB todavía no tiene factores desencadenantes, pero se puede conectar su aplicación a la cola de la colección oplog y hacer algo cada vez se elimina un documento (o actualiza, o se inserta, etc.)

La entrada en el blog 3 parte aquí podría ser útil sobre cómo hacer esto: http://www.kchodorow.com/blog/2010/10/12/replication-internals/

+1

Ese enlace está muerto ahora. – captncraig

+1

Gracias por señalarlo. Lo he arreglado en la publicación. – Sid

2

¿Qué quiere decir que los mongodbs están sincronizados? ¿Están realmente replicando datos entre ellos? Supongo que no, ya que parece que quieres administrar esa sincronización.

En el pasado, he logrado algo similar con MongoDB y asp que requiere una instancia de mongo centralizada (par de réplicas, etc.). Básicamente, cada vez que se realiza un cambio en la instancia local, una colección con tope en la instancia central también se actualiza con la nueva versión del valor de configuración y una marca de tiempo de cuándo ese valor se actualizó por última vez y qué servidor actualizó el valor.

A continuación, se ejecuta un subproceso independiente en los servidores individuales que mantiene abierto un cursor de lista contra la instancia central. Cada vez que el cursor recupera un nuevo registro, los nuevos valores se comparan con la marca de tiempo de la instancia local y se actualizan en consecuencia (o no). Debe tener cuidado al comparar esas marcas de tiempo y el servidor "autoritativo" que realizó el cambio para asegurarse de que no termina con una tormenta de actualización. También debe saber si la actualización se debe a que alguien realmente cambió el valor o si es porque el valor fue "replicado"; no desea actualizar la instancia central si la actualización es una actualización de replicación.

0

A partir de mongodb 3.6, ahora puede conectar acciones al flujo de cambios. Esto le proporciona un cursor disponible que puede usar para escuchar los cambios (por ejemplo, operaciones crud) en una colección en particular.

La secuencia de cambio está construida en la parte superior del oplog y está accesible para todo lo que esté utilizando el oplog. Cambio corrientes son resumable y también se puede utilizar con los operadores de agregación como $ partido, proyecto ... $

Más información aquí (Java ejemplo): http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/

Y aquí está el fragmento de https://www.mongodb.com/mongodb-3.6 (Java):

// 1. The database for reactive, real-time applications 
MongoClient mongoClient; 

// Create a new MongoClient with a MongoDB URI string. 
if (args.length == 0) { 
// Defaults to a localhost replicaset on ports: 27017, 27018, 27019 
    mongoClient = new MongoClient(new 
    MongoClientURI("mongodb://localhost:27017,localhost:27018,localhost:27019")); 
} else { 
    mongoClient = new MongoClient(new MongoClientURI(args[0])); 
} 

// Select the MongoDB database. 
MongoDatabase database = mongoClient.getDatabase("testChangeStreams"); 
database.drop(); 
sleep(); 

// Select the collection to query. 
MongoCollection<Document> collection = database.getCollection("documents"); 

// Create the change stream cursor. 
MongoCursor<Document> cursor = collection.watch().iterator(); 

Si está trabajando en C#, se pueden encontrar ejemplos here:

var inventory = database.GetCollection<BsonDocument>("inventory"); 

    var document = new BsonDocument("x", 1); 
    inventory.InsertOne(document); 
    new Thread(() => 
    { 
     Thread.Sleep(TimeSpan.FromMilliseconds(100)); 
     var filter = new BsonDocument("_id", document["_id"]); 
     var update = "{ $set : { x : 2 } }"; 
     inventory.UpdateOne(filter, update); 
    }) 
    .Start(); 

    // Start Changestream Example 2 
    var options = new ChangeStreamOptions { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup }; 
    var enumerator = inventory.Watch(options).ToEnumerable().GetEnumerator(); 
    enumerator.MoveNext(); 
    var next = enumerator.Current; 
    enumerator.Dispose(); 
    // End Changestream Example 2 

    var expectedFullDocument = document.Set("x", 2); 
    next.FullDocument.Should().Be(expectedFullDocument); 
Cuestiones relacionadas