PG 在高并发请求上承诺过多的客户端
Posted
技术标签:
【中文标题】PG 在高并发请求上承诺过多的客户端【英文标题】:PG Promise too many client on high concurrent request 【发布时间】:2022-01-05 11:21:02 【问题描述】:我试图根据从其他表中选择的数据插入数百/千个数据,但我发现一个错误“客户端太多”,这里是错误
我正在使用 pgp (pg promise) 库,这是我的 sn-p
function call()
for (let index = 0; index < 5; index++)
getPendingData().then((result) =>
db.tx((t) =>
let counter = 0;
const queries = result.map((data) =>
counter++;
return db.none(`insert into test_data (id, isdeleted, parentid) values ('$uuidv1()', 0, '$uuidv1()x-$uuidv1()' ) `);
);
return t.batch(queries);
);
);
let getPendingData = async () =>
return db.task('getPendingData', async (t) =>
return await t.any('select * from other_table');
);
(call())
im setup max pg conn 为 100, 任何线索如何在不添加 max conn 的情况下解决这个问题?
【问题讨论】:
安装uuid-ossp,然后运行一个insert into test_data (id, isdeleted, parentid) select uuid_generate_v1()::text, 0, uuid_generate_v1()::text || 'x-' uuid_generate_v1()::text from other_table;
查询。
@Bergi 我认为问题不是来自 uuid,而是来自客户端 conn
不,问题出在您的方法上。如果数据库可以在一个简单的单个查询中完成所有工作,请不要对数据库进行百分之一或数千次查询(即使在事务中)。
但是我需要在选定的查询上插入很多数据库,并且查询返回一千行
只需将查询拆分为块,仅并行运行块查询并按顺序处理所有块。例如,您可以使用 lodash
chunk
函数拆分查询数组
【参考方案1】:
你的代码问题太多了,很遗憾……
你如何使用 Promise 和你如何使用 pg-promise
都是不正确的。
promise 的问题是你应该链接它们,这意味着使用来自 db.tx
(return db.tx(...)
) 的结果,你没有这样做,创建一个松散的 promise,结果,与事务相关的松散连接。另外,return await
是一种反模式。
pg-promise
使用的问题是您应该针对您正在创建的事务/任务上下文 t
(as shown here) 执行查询。但是您正在针对 db
执行每个查询 - 而不是根连接,这会产生无数的连接请求。
另外,创建一个只执行一个查询的任务没有任何意义。
如果这还不够糟糕,您正在对值进行字符串连接,这在查询格式中是一个严格的禁忌。
最后,多个插入应该作为多行查询执行,而不是作为单独的查询执行,这会浪费性能 - 请参阅multi-row inserts。
【讨论】:
感谢pg-promise
:)
@madflow 不客气! :)
感谢您的建议以上是关于PG 在高并发请求上承诺过多的客户端的主要内容,如果未能解决你的问题,请参考以下文章