2012-04-04 2 views
7

Próbuję użyć mongodb jako pamięci konfiguracyjnej w całej sieci. Ta sama aplikacja działa na wielu komputerach w sieci, każda pobiera swoją konfigurację z lokalnego mongodb. Mononomy są zsynchronizowane. Chciałbym uzyskać wywołanie zwrotne/powiadomienie we wszystkich aplikacjach n-1, jeśli jedna aplikacja zmieni jedną z wartości konfiguracyjnych. Czy to możliwe?Otrzymuj powiadomienia o zmienionych dokumentach w mongodb

(Byłoby ocal mnie od robienia transfer sieciowy/syncronisation itp siebie.)

Odpowiedz

9

MongoDB nie ma jeszcze wyzwalacze, ale można podłączyć aplikację do ogona off kolekcji oplog i zrobić coś za każdym razem dokument został usunięty (lub zaktualizowane, lub włożona, itd.)

Blog post 3 część tutaj mogą być pomocne w jaki sposób to zrobić: http://www.kchodorow.com/blog/2010/10/12/replication-internals/

+1

Ten link jest już martwy. – captncraig

+1

Dzięki za wskazanie. Naprawiłem to w poście. – Sid

2

Co masz na myśli, że mongodbs są zsynchronizowane? Czy faktycznie między sobą replikują dane? Zakładam, że nie, ponieważ brzmi to tak, jakbyś chciał zarządzać tą synchronizacją.

W przeszłości osiągnąłem coś podobnego w MongoDB i asp, które wymagają scentralizowanej instancji mongo (para replik itd.). Zasadniczo, za każdym razem, gdy dokonywana jest zmiana w instancji lokalnej, kolekcja ograniczona na instancji centralnej jest również aktualizowana o nową wersję wartości konfiguracyjnej i znacznik czasu, kiedy ta wartość była ostatnio aktualizowana i który serwer zaktualizował wartość.

Oddzielny wątek jest następnie uruchamiany na poszczególnych serwerach, które utrzymują otwarty kursywę do instancji centralnej. Za każdym razem, gdy nowy rekord jest pobierany przez kursor, nowe wartości są porównywane ze znacznikiem czasowym instancji lokalnej i są odpowiednio aktualizowane (lub nie). Należy zachować ostrożność podczas porównywania tych znaczników czasu i "autorytatywnego" serwera, który wprowadził zmianę, aby upewnić się, że nie zakończy się aktualizacja burzy. Musisz także wiedzieć, czy aktualizacja jest spowodowana tym, że ktoś faktycznie zmienił wartość lub czy jej wartość została "zreplikowana" - nie chcesz aktualizować instancji centralnej, jeśli aktualizacja jest aktualizacją replikacji.

0

Od wersji mongodb 3.6 można teraz przechwytywać akcje do strumienia zmian. W ten sposób można ustawić kursywę, której można użyć do odsłuchiwania zmian (np. Operacji crud) na konkretnej kolekcji.

Strumień zmian jest zbudowany na wierzchu oploga i jest dostępny dla wszystkiego, co używa oploga. Zmiany strumienie są wznawialną i może być również używany z operatorów agregacji takich jak $, $ meczu projektu ...

Więcej informacji tutaj (przykład Java): http://mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/

A oto fragment z 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(); 

Jeśli pracujesz w C#, przykłady można znaleźć 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);