MongoDB 并发

Concurrency in MongoDB

我正在使用集合 requests 作为多个客户端同时读取的队列。每个客户端将一次从 requests 中读取一个文档,然后将其从集合中删除。我能否确保每个文档仅由 1 个客户端读取和处理?

客户端是用Python用pymongo编写的。

这里的基本步骤是使用.findAndModify():

请原谅,这不是 python 代码,但结构相同,是一个合理的通用示例。三个文件:

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

所以从核心方法开始,您只需在每个 _id 上使用 "remove" 参数调用它。没有其他进程可以同时执行此操作。

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

这将 return 删除的文档或什么都没有。


为了获得更多 "concurrency" 证明,请再次原谅此处的 node.js 代码,但我不打算做一些出色的 "Twisted" 类型代码作为快速示例。它用于并发测试的目的:

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();
  }
);

结果(顺序可能不同):

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

因此,在此处的 6 次尝试 运行 中,每个文档有两次尝试,实际上只有 3 次尝试成功,并且 returned 将结果从堆栈中取出。

这就是保证你想要的结果的原则。

您似乎在寻找

db.requests.findAndModify()

根据文档,如果您将其与主字段上的唯一索引一起使用,您应该会找到一个好地方。

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