Node.JS MongoDB发现:顺序比并行更快,为什么?
我遇到了一个奇怪的行为,与我认为我对mongodb的了解相矛盾:
我有4个空集合。我在每个集合和度量上做一个find
,查询将持续多长时间才能完成。
对于“并行”测试,我使用await Promise.all(queries)
开始所有查询。对于“顺序”测试,我使用“等待查询[0..3]”启动所有查询。
我希望,由于集合是空的,测量的时间通常很低,并行请求的执行速度比顺序请求快一点。查询转向localhost - 意味着将数据从客户端传输到mongodb服务器并返回不会增加太多开销。
然而;结果:
平行:2008 ms
顺序:2毫秒
也许我的代码有问题?
当我在循环中多次执行查询时,我收到以下结果:
并行1:2008.642 ms
顺序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();
编译的代码可以在这里找到:
最好的祝福
回答如下:由于这种行为,我希望有理由在我的Node.JS代码或MongoDB Node.JS驱动程序中。
你是对的!它位于mongo-client池中。首次创建池时,它只有一个连接。当您一次询问4个请求时,它会尝试打开更多连接,并且通常似乎处于不良状态。 http://mongodb.github.io/node-mongodb-native/core/driver/reference/pool/
如果将poolSize
设置为1用于连接,则应该在并行和串行之间看到类似的性能。还有一个minSize
option将使用适当数量的连接初始化连接池,并确保池大小永远不会低于最小大小。
Node.JS MongoDB发现:顺序比并行更快,为什么?
我遇到了一个奇怪的行为,与我认为我对mongodb的了解相矛盾:
我有4个空集合。我在每个集合和度量上做一个find
,查询将持续多长时间才能完成。
对于“并行”测试,我使用await Promise.all(queries)
开始所有查询。对于“顺序”测试,我使用“等待查询[0..3]”启动所有查询。
我希望,由于集合是空的,测量的时间通常很低,并行请求的执行速度比顺序请求快一点。查询转向localhost - 意味着将数据从客户端传输到mongodb服务器并返回不会增加太多开销。
然而;结果:
平行:2008 ms
顺序:2毫秒
也许我的代码有问题?
当我在循环中多次执行查询时,我收到以下结果:
并行1:2008.642 ms
顺序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();
编译的代码可以在这里找到:
最好的祝福
回答如下:由于这种行为,我希望有理由在我的Node.JS代码或MongoDB Node.JS驱动程序中。
你是对的!它位于mongo-client池中。首次创建池时,它只有一个连接。当您一次询问4个请求时,它会尝试打开更多连接,并且通常似乎处于不良状态。 http://mongodb.github.io/node-mongodb-native/core/driver/reference/pool/
如果将poolSize
设置为1用于连接,则应该在并行和串行之间看到类似的性能。还有一个minSize
option将使用适当数量的连接初始化连接池,并确保池大小永远不会低于最小大小。