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/
我正在使用集合 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/