我遇到了一种奇怪的行为,这种行为与我对mongodb的了解相矛盾:
我有4个空的收藏品。我对每个集合进行find
,并测量查询需要多长时间才能完成。
对于";平行的"-测试,我使用await Promise.all(queries)
启动所有查询。对于";顺序的"-测试时,我使用";等待查询[0..3]";。
我预计,由于集合是空的,测量的时间通常很低,并行请求的执行速度比顺序请求快一点。查询指向localhost,这意味着将数据从客户端传输到mongodb服务器并返回不会增加太多开销。
然而;结果:
并行:2008ms
顺序:2ms
也许我的代码有问题?
当我在一个循环中多次执行查询时,我会收到以下结果:
并行1:2008.642毫秒
顺序1:2.344 ms
并行2:1004.544ms
顺序2:5.273ms
并行3:2.152ms
顺序3:3.605ms
并行4:2.189ms
顺序4:3.885ms
每当我重新启动程序时,我都会收到类似的结果(无论是否删除/重新创建集合)。
我的问题是:为什么并行查询比顺序查询需要更多的时间为什么每次请求完成后并行请求都会加快,但当我重新启动Node.JS软件时会重置请求持续时间?
由于这种行为,我希望原因在我的Node.JS代码或MongoDB Node.JS驱动程序中。
我的代码:
import {
MongoClient,
ObjectID,
} from 'mongodb';
const run = async () => {
const client = await MongoClient.connect('mongodb://localhost:27017/mydatabase', {
useNewUrlParser: true
}),
db = client.db('mydatabase'),
userId = new ObjectID();
// create collections
await db.dropCollection('collection1');
await db.dropCollection('collection2');
await db.dropCollection('collection3');
await db.dropCollection('collection4');
await db.createCollection('collection1');
await db.createCollection('collection2');
await db.createCollection('collection3');
await db.createCollection('collection4');
// measure read fullfill times
for (let i = 1; i < 5; ++i) {
console.time(`Parallel ${i}`);
await Promise.all([
db.collection('collection1')
.find()
.toArray(),
db.collection('collection2')
.find()
.toArray(),
db.collection('collection3')
.find()
.toArray(),
db.collection('collection4')
.find()
.toArray(),
]);
console.timeEnd(`Parallel ${i}`);
console.time(`Sequential ${i}`);
await db.collection('collection1')
.find()
.toArray();
await db.collection('collection2')
.find()
.toArray();
await db.collection('collection3')
.find()
.toArray();
await db.collection('collection4')
.find()
.toArray();
console.timeEnd(`Sequential ${i}`);
}
};
run();
编译后的代码可以在这里找到:https://pastebin.com/ETmPPbzd
向致以最良好的问候
由于这种行为,我希望原因在我的Node.JS代码或MongoDB Node.JS驱动程序中。
是的,你说得对!它在mongo客户端池中。当您第一次创建池时,它只有一个连接。当你一次问4个请求时,它会尝试打开更多的连接,通常看起来会进入糟糕的状态。http://mongodb.github.io/node-mongodb-native/core/driver/reference/pool/
如果您将连接的poolSize
设置为1,那么在parallel&电视连续剧还有一个minSize
选项,它将使用适当数量的连接初始化连接池&确保池大小永远不会低于最小大小。