12

我正在尝试使用 mongodb 作为网络范围的配置存储。这个相同的应用程序在网络上的多台机器上运行,每台机器都从其本地 mongodb 中提取其配置。mongodbs 已同步。如果一个应用程序更改了任何配置值,我想要的是在所有 n-1 个应用程序中获得回调/通知。这种设置可能吗?

(这将使我免于自己进行网络传输/同步等。)

4

3 回答 3

10

从 mongodb 3.6 开始,您现在可以将操作挂钩到更改流。这为您提供了一个可尾光标,您可以使用它来监听特定集合上的更改(例如 crud 操作)。

变更流建立在 oplog 之上,任何使用 oplog 的东西都可以访问。更改流是可恢复的,也可以与聚合运算符一起使用,例如 $match、$project...

更多信息(Java 示例): http: //mongodb.github.io/mongo-java-driver/3.6/driver/tutorials/change-streams/

这是来自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();

如果您使用 C#,可以在此处找到示例:

    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);
于 2017-11-08T16:24:26.507 回答
8

MongoDB 还没有触发器,但是您可以挂钩您的应用程序以终止 oplog 集合,并在每次删除(或更新或插入等)文档时执行一些操作

此处的 3 部分博客文章可能对如何执行此操作有所帮助: http ://www.kchodorow.com/blog/2010/10/12/replication-internals/

于 2012-04-04T17:19:22.513 回答
2

你是什​​么意思mongodbs是同步的?他们真的在彼此之间复制数据吗?我认为不会,因为这听起来好像您想管理该同步。

过去,我用 MongoDB 和 asp 完成了类似的事情,这需要一个集中的 mongo 实例(副本对等)。基本上,每次对本地实例进行更改时,中央实例上的上限集合也会使用新版本的配置值以及该值上次更新时间和哪个服务器更新该值的时间戳进行更新。

然后在各个服务器上运行一个单独的线程,该线程使可尾游标对中央实例保持打开状态。每当游标检索到新记录时,都会将新值与本地实例的时间戳进行比较,并相应地更新(或不更新)。在比较那些时间戳和进行更改的“权威”服务器时必须小心,以确保您不会遇到更新风暴。您还需要知道更新是因为有人实际更改了值还是因为该值被“复制”了 - 如果更新是复制更新,您不想更新中央实例。

于 2012-04-04T18:57:43.610 回答