PostgreSQL数据库 OLTP高并发请求性能优化
发布时间:2020-12-13 18:13:14 所属栏目:百科 来源:网络整理
导读:在多核系统中,一般TPS会随并发数的增加而提升,但是当并发数超过一定的数值(如CPU核数的2到3倍以后),性能开始下降,并发数越高,下降越严重。 例子: 更新500万记录表中的1条随机记录。开8000个并发。 create table test_8000 ( id int primary key , cn
在多核系统中,一般TPS会随并发数的增加而提升,但是当并发数超过一定的数值(如CPU核数的2到3倍以后),性能开始下降,并发数越高,下降越严重。
例子:
更新500万记录表中的1条随机记录。开8000个并发。
每次加载80个并发,循环100次,一共加载8000个并发。
vi testsh
#!/bin/bash
for ((i=0;i<100;i++))
do
sleep pgbench -M simple n r f ./tsql c 80 j T 100000U postgres &
done
开始
当连接数达到8000后,观察TPS,我们可以使用PG的统计信息表来计算QPS。
postgres=# select count(*) from pg_stat_activity;
count
-------
8002
(1 row)
# select timestamptz '2015-10-08 17:01:24.203089+08' - timestamptz '2015-10-08 17:01:16.574076+08';
?column?
-----------------
00:00:07.629013
# select 43819090-43749480;
?column?
----------
69610
# select 69610/07.629013;
?column?
-----------------------
9124.3782124896103860
(1 row)
8000个并发的时候,更新TPS约9124。大部分时间可能浪费在CPU调度上了。
另一种场景,
如果有8000个并发是空闲连接,只有10个在执行更新,性能是这样的:
先制造8000个空闲连接:
select pg_sleep100000done
sh
然后开启10个连接执行更新操作。
M prepared P 101000U postgres postgres
progress:1.0 s29429.2 tps lat 0.336 ms stddev 0.109
progress2.028961.10.3430.114
3.030433.80.3260.103
4.029597.15.028714.10.3460.117
6.028319.00.3510.121
7.028540.00.3480.118
8.029408.90.3380.111
9.029178.10.3400.119
10.029146.90.34111.027498.50.3610.123
这种方法的性能约6万 qps。
优化思路:
排队处理用户请求。类似pgbouncer或Oracle的shared server机制,真实处理请求的进程数有限。
使用PostgreSQL的advisory函数可以模拟这种排队机制:
create or replace function updl intv_id ) returns voidas $$
declare
begin
LOOP
if pg_try_advisory_xact_locklthen--只有获得这个应用级锁才执行更新,否则就等待。
update test_8000 v_id returnelse
perform pg_sleep30*random());随机等待时间
endifEND LOOP;
end$$ language plpgsql strict
增加一个随机变量l,用来表示应用所的号码,也就是说模拟10个同时在更新的操作,其他的都在等待。
这个是没有经过优化的排队机制,因为不是独立的进程处理用户请求,依旧是backend process在处理用户请求,依旧有8000个进程。
5000000
setrandom l 10
select(:sh
#!/bin/bash
for ((i=0;i<100;i++))
do
;
&
done
sh
测试结果比较理想,已经提升了1倍性能。
# select now(),n_tup_upd+n_tup_hot_upd from pg_stat_all_tables where relname='test_8000'; now |?column -------------------------------+----------- 2015-100819:0637.951332221045069 row)
------------------------------+----------- 0746.46325222879057 # select timestamptz '2015-10-08 19:07:46.46325+08' - timestamptz '2015-10-08 19:06:37.951332+08'; ----------------- 000108.511918 # select 222879057-221045069; ---------- 1833988 # select 1833988/68.5; -------------------- 26773.547445255474 )
模拟结果,相比不排队,有1倍以上的性能提升。
TOP
top 0937 up 119 days359 users load average0.960.981.01
Tasks8872 total 5 running8866 sleeping stopped0 zombie
Cpus):5.3%us0.8sy0.0ni93.9wahisist
Mem132124976k118066688k used14058288k free316752k buffers
Swap2097144k 148k2096996k63702028k cached
advisory lock是PG提供的一种轻量级的面向用户的锁(当然比LWLOCK是要重的),我之前在秒杀场景的优化中也有叙述,可以达到每秒处理19万次的单条记录更新请求的性能,并且保持1毫秒以内的RT。请参考。
http://blog.163.com/digoal@126/blog/static/16387704020158149538415/
把这种优化思路加入到PostgreSQL的内核中是比较靠谱的,最终实现的效果会和Oracle的shared server非常类似。
阿里云PG内核组的小鲜肉和老腊肉们,优化开始搞起吧。
在没有优化前,还是使用pgbouncer这种连接池吧。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |