[英]many queries postgres (node), no parallel queries?
我正在使用postgres-node(pg)包運行節點服務器。
我編寫了一個程序,該程序立即向我的postgres數據庫請求n個查詢(例如20,000個)。
當我與幾個也想一次查詢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();
}
});
首先,你需要創建一個連接池,這里與節點的一個例子皮克為了方便單獨的模塊(節點PG-sql.js):
node-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連接都會消耗RAM來管理連接或使用該連接的客戶端。 您擁有的連接越多,將使用的RAM越多,則可以用來運行數據庫。
在增加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 });
}
})
});
}
編輯:
“沒有並行性。”
節點是異步的,您可以使用諾言,也可以產生更多的客戶端/池並調整最大連接數(如我的回答所述,但要牢記主機的性能),但是多個客戶端運行大約20.000個查詢,他們不會立即或並行解決結果。 您試圖實現的確切目標是什么?
“這對postgres是正常的行為嗎?”
這是由於節點的事件循環以及運行Postgres的主機的某些性能限制所致。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.