首页 > 解决方案 > Node.JS MongoDB 发现:顺序比并行快,为什么?

问题描述

我遇到了一个奇怪的行为,这与我认为我对 mongodb 的了解相矛盾:

我有 4 个空集合。我find对每个收集和测量进行一次,查询需要多长时间才能完成。

对于“并行”测试,我使用await Promise.all(queries). 对于“顺序”测试,我使用“等待查询 [0..3]”开始所有查询。

我希望,由于集合是空的,测量的时间通常非常低,并行请求的执行速度比顺序请求快一点。查询指向 localhost - 这意味着将数据从客户端传输到 mongodb 服务器并返回不应该增加太多开销。

然而; 结果:

并行:2008毫秒

连续:2毫秒

也许我的代码有问题?

当我在一个循环中多次执行查询时,我收到以下结果:

并行 1:2008.642 毫秒

顺序 1:2.344 毫秒

并行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.jsmongodbasynchronouspromiseasync-await

解决方案


由于这种行为,我希望原因在于我的 Node.JS 代码或 MongoDB Node.JS 驱动程序中的某个地方。

你是对的!它在 mongo-client 池中。首次创建池时,它只有一个连接。当您一次提出 4 个请求时,它会尝试打开更多连接,并且通常似乎会进入错误状态。http://mongodb.github.io/node-mongodb-native/core/driver/reference/pool/

如果您将您poolSize的连接设置为 1,您应该会看到并行和串行之间的类似性能。还有一个minSize选项可以使用适当数量的连接初始化连接池并确保池大小永远不会低于最小大小。


推荐阅读