简体   繁体   English

MongoDB中的并发

[英]Concurrency in MongoDB

I'm using the collection requests as a queue that multiple clients read from concurrently. 我将收集requests用作多个客户端同时读取的队列。 Each client will read one document at a time from requests and then remove it from the collection. 每个客户一次从requests读取一个文档,然后将其从集合中删除。 Can I ensure that each document is read and processed by only 1 client? 我可以确保每个文档只能由1个客户端读取和处理吗?

The clients are written in Python with pymongo. 客户端是用pymongo用Python编写的。

The basic procedure here is to use .findAndModify() : 这里的基本过程是使用.findAndModify()

Forgive that this is not python code, but the structure is the same and it's a reasonable universal example. 原谅这不是python代码,但结构相同,是一个合理的通用示例。 Three documents: 三个文件:

{ "_id": 1 }
{ "_id": 2 }
{ "_id": 3 }

So from the core method, you just call it with the "remove" argument on each _id . 因此,从核心方法中,您只需在每个_id上使用“ remove”参数来调用它。 No other process can do this at the same time. 没有其他进程可以同时执行此操作。

db.collection.findAndModify({
    "query": { "_id": 1 },
    "remove": true
})

That will either return the document that was removed or nothing at all. 那要么返回被删除的文档,要么什么都不返回。


For a bit more "concurrency" proof, again excuse the node.js code here but I'm not in a frame to do some briliant "Twisted" type code as a quick example. 为了获得更多的“并发性”证明,请再次在这里原谅node.js代码,但是我不打算做一些简单的“ Twisted”类型代码作为快速示例。 It serves the purpose of a concurrency test though: 但是,它可以达到并发测试的目的:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var testSchema = new Schema({
  "_id": Number,
});

var Test = mongoose.model( 'Test', testSchema, 'test' );

mongoose.connect('mongodb://localhost/async');

async.series(
  [
    // Clear test collection
    function(callback) {
      Test.remove({},callback)
    },

    // Insert some data
    function(callback) {
      async.each([1,2,3],function(num,callback) {
        Test.create({ "_id": num },callback);
      },callback);
    },

    // Now run test in parallel
    function(callback) {
      async.each([1,1,2,2,3,3],function(num,callback) {
        Test.findOneAndRemove(
          { "_id": num },
          function(err,doc) {
            if (err) callback(err);
            console.log( "Removing: %s, %s", num, doc );
            callback();
          }
        );
      },callback);
    }
  ],
  function(err) {
    process.exit();
  }
);

And results (in possible varying order ) : 结果(可能有变化的顺序):

Removing: 3, { _id: 3, __v: 0 }
Removing: 1, { _id: 1, __v: 0 }
Removing: 3, null
Removing: 1, null
Removing: 2, { _id: 2, __v: 0 }
Removing: 2, null

So out of the six attempts run here with two attempts per document, only 3 of the attempts actually succeeded and returned the result pulled off of the stack. 因此,在这里进行的六次尝试中,每个文档两次尝试,实际上只有3次尝试成功,并返回了从堆栈中拉出的结果。

That's the principle to ensuring the result you want. 这是确保获得所需结果的原则。

Looks like you're looking for 看起来像您要找的

db.requests.findAndModify()

According to the documentation, if you use this with a unique index on the main field you should end up in a good place. 根据文档,如果将它与主字段上的唯一索引一起使用,则应该放在一个合适的位置。

http://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/ http://docs.mongodb.org/manual/reference/method/db.collection.findAndModify/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM