Node.JS MongoDB находят: последовательно быстрее, чем параллельно, почему? - PullRequest
0 голосов
/ 11 февраля 2019

Я столкнулся со странным поведением, которое противоречит тому, что я думал о mongodb:

У меня 4 пустых коллекции.Я делаю find для каждой коллекции и измеряю, сколько времени потребуется для выполнения запросов.

Для "параллельного" теста я запускаю все запросы, используя await Promise.all(queries).Для «последовательного» теста я запускаю все запросы, используя «await query [0..3]».

Я ожидаю, что из-за пустых коллекций измеренное время в целом довольно малос параллельным запросом, выполняющимся немного быстрее, чем последовательный.Запросы направляются в сторону localhost - это означает, что передача данных с клиента на сервер mongodb и обратно не должна приводить к большим накладным расходам.

Однако;результаты:

параллельно: 2008 мс

последовательно: 2 мс

Возможно мой кодесть проблемы?

Когда я выполняю запросы несколько раз в цикле, я получаю следующие результаты:

Параллельно 1: 2008.642 мс

Последовательность 1: 2.344мс

Параллель 2: 1004,544мс

Последовательность 2: 5,273мс

Параллель 3: 2,152мс

Последовательность 3: 3,605 мс

Параллельный 4: 2,189 мс

Последовательный 4: 3,885 мс

Каждый раз, когда я перезапускаю программу, я получаю аналогичные результаты (с удалением или повторным созданием коллекций).

Мой вопрос: Почему параллельным запросам требуется больше времени, чем последовательным? И почему параллельные запросы ускоряются с каждым выполненным запросом, но сбрасывают длительность запроса при перезапуске 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

С уважением

1 Ответ

0 голосов
/ 11 февраля 2019

Из-за поведения я ожидаю, что причина лежит где-то в моем коде Node.JS или в драйвере MongoDB Node.JS.

Да, вы правы!Это в пуле монго-клиентов.Когда вы впервые создаете пул, он имеет одно соединение.Когда вы запрашиваете 4 запроса одновременно, он пытается открыть больше соединений и, как правило, кажется, что находится в плохом состоянии.http://mongodb.github.io/node-mongodb-native/core/driver/reference/pool/

Если вы установите poolSize на 1 для вашего соединения, вы должны увидеть аналогичную производительность между параллельным и последовательным интерфейсом.Также имеется опция minSize , которая инициализирует пул соединений с соответствующим количеством соединений и гарантирует, что размер пула никогда не опускается ниже минимального размера.

...