Как выполнять запросы во время потока, используя pg-обещание - PullRequest
0 голосов
/ 20 мая 2019

Я пытаюсь выполнить запрос вставки для каждой строки потока запросов, используя pg-обещание с pg-query-stream. При таком подходе использование памяти увеличивается с каждым выполненным запросом.

Я также сузил проблему до выполнения любого запроса во время потока, а не только вставки. В настоящее время я слушаю события «данных» в потоке, приостанавливаю поток, выполняю запрос и возобновляю поток. Я также попытался передать поток запросов в поток для записи, который выполняет запрос, но я получаю сообщение об ошибке, что соединение БД уже закрыто.

let count = 0;
const startTime = new Date();

const qs = new QueryStream('SELECT 1 FROM GENERATE_SERIES(1, 1000000)');

db.stream(qs, stream => {
    stream.on('data', async () => {
        count++;
        stream.pause();
        await db.one('SELECT 1');
        if (count % 10000 === 0) {
            const duration = Math.round((new Date() - startTime) / 1000);
            const mb = Math.round(process.memoryUsage().heapUsed/1024/1024);
            console.log(`row ${count}, ${mb}MB, ${duration} seconds`);
        }
        stream.resume();
    });
});

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

row 10000, 105MB, 4 seconds
row 20000, 191MB, 6 seconds
row 30000, 278MB, 9 seconds
row 40000, 370MB, 10 seconds
row 50000, 458MB, 14 seconds

Чтобы достичь строки 60000, требуется более 10 минут.

UPDATE:

Я отредактировал приведенный выше код, добавив в него async / await, чтобы дождаться завершения внутреннего запроса, и увеличил ряд до 10 000 000. Я запустил процесс узла с 512 МБ памяти, и программа значительно замедляется при приближении к этому пределу, но не вылетает. Эта проблема возникла с v10, а не с v11 + узла.

1 Ответ

0 голосов
/ 22 мая 2019

Это связано с неправильным использованием обещаний / асинхронного кода.

Строка db.one('SELECT 1'); не привязана ни к чему, порождая свободные обещания с высокой скоростью, что, в свою очередь, загрязняет память.

Вам нужно связать это либо с .then.catch, либо с await.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...