Много запросов postgres (узел), нет параллельных запросов?
Я использую сервер узлов с пакетом postgres-node (pg).
Я написал программу, которая одновременно запрашивает n-запросов (например, 20 000) в моей базе данных postgres.
Когда я делаю это с несколькими клиентами, которые хотят одновременно запросить 20 000, параллелизма нет. Это означает, что запросы второго клиента будут поставлены в очередь, пока первый клиент не завершит все свои запросы.
Это нормальное поведение для postgres? Если да, как я могу предотвратить, чтобы один пользователь получил все ресурсы (а другие должны были ждать), если нет параллельности?
Это мой код:
const express = require('express');
const app = express();
const { Pool } = require("pg");
const pool = new Pool();
benchmark(){
pool.connect((err, client, done) => {
if (err) throw err;
client.query("SELECT * from member where m_id = $1", [1], (err, res) => {
done();
if (err) {
console.log(err.stack);
} else {
console.log(res.rows[0]);
}
});
});
}
app.get('/', function(req, res) {
for(let i=0;i<20000;i++){
benchmark();
}
});
1 ответ
Сначала вам нужно создать пул соединений, вот пример с pg узла в отдельном модуле (node-pg-sql.js) для удобства:
узел-Pg-sql.js:
const { Pool } = require('pg');
const pool = new Pool(fileNameConfigPGSQL);
module.exports = {
query: (text, params, callback) => {
const start = Date.now()
return pool.query(text, params, (err, res) => {
const duration = Date.now() - start
// console.log('executed query', { text, duration, rows: res.rowCount })
callback(err, res)
})
},
getClient: (callback) => {
pool.connect((err, client, done) => {
const query = client.query.bind(client)
// monkey patch
client.query = () => {
client.lastQuery = arguments
client.query.apply(client, arguments)
}
// Timeout 5 sek
const timeout = setTimeout(() => {
// console.error('A client has been checked out for more than 5 seconds!')
// console.error(`The last executed query on this client was: ${client.lastQuery}`)
}, 5000)
const release = (err) => {
// 'done' Methode - returns client to the pool
done(err)
// clear Timeouts
clearTimeout(timeout)
// reset der Query-Method before Monkey Patch
client.query = query
}
callback(err, client, done)
})
}
}
В вашем postgresql.conf (на linux обычно в /var/lib/pgsql/data/postgresql.conf) установите max-connection желаемое значение:
max_connection = 300
Иметь ввиду:
Каждое соединение PostgreSQL использует оперативную память для управления соединением или клиентом, использующим его. Чем больше у вас подключений, тем больше оперативной памяти вы будете использовать, чтобы вместо этого использовать ее для запуска базы данных.
Увеличивая ваши max-connections
нужно увеличить shared_buffers
а также kernel.shmmax
а также для того, чтобы увеличение клиентского соединения было эффективным.
Всякий раз, когда вы хотите выполнить запрос с одного из ваших маршрутов / конечных точек, просто требуется отдельный файл пул клиента, например:
const db = require('../../../node-pg-sql');
module.exports = (router) => {
router.get('/someRoute', (req, res) => {
console.log(`*****************************************`);
console.log(`Testing pg..`);
let sqlSelect = `SELECT EXISTS (
SELECT 1
FROM pg_tables
WHERE schemaname = 'someschema'
)`;
db.query(sqlSelect, (errSelect, responseSelect) => {
if (errSelect) {
/* INFO: Error while querying table */
console.log(`*****************************************`);
console.log(`ERROR WHILE CHECKING CONNECTION: ${errSelect}`);
}
else {
// INFO: No error from database
console.log(`*****************************************`);
console.log(`CONNECTION TO PGSQL WAS SUCCESSFUL..`);
res.json({ success: true, message: responseSelect, data:responseSelect.rows[0].exists });
}
})
});
}
РЕДАКТИРОВАТЬ:
"нет параллели.."
Узел асинхронный, вы можете работать с обещаниями или порождать больше клиентов / пулов и настраивать ваши max-соединения (как объяснено в моем ответе, но помните о производительности вашей хост-машины), но с несколькими клиентами, выполняющими около 20000 запросов, они не разрешатся с результатом мгновенно или параллельно. Какую именно цель вы пытаетесь достичь?
"Это нормальное поведение для postgres?"
Это связано с циклом событий узла, а также с определенным ограничением производительности хост-машины, на которой работает Postgres.