在MPP默认的连接行为之外,实现一种新的连接池管理方式,称为实时连接池管理,MPP实时执行器实时管理协调节点到每个worker节点的连接池大小,以及每个用户建立的到劝拿庞蜗菲教ㄗ⒉嵬净个worker节点连接池大小,简称前者为单worker连接池管理,后者为单用户连接池管理。当单worker连接池大小已达上限,或者单用户连接池大小已达上限时,实时执行器阻塞那些需要创建新连接的任务,只处理连接状态为“已建立”的任务。用户可自由配置单worker连接池上限和单用户连接池上限。
为了限制单个worker的已打开连接数,以及限制单用户的已打开连接数,现在对任务处理过程进行优化。连接池创建模块建立进程共享的两个连接池-单worker连接池和单用户连接池-分别记录单worker上的实时已打开连接数和单用户的实时已打开连接数。连接池管理模块负责向连接池中插入新记录,查询及更新记录。
连接池管理模块利用查询记录功能,检测相应入口的已打开连接数,只有当任务处理节点的已打开连接数未达上限,且当前用户在处理节点的已打开连接数未达上限时,才允许处理“准备开始”的任务。连接池管理模块的更新记录功能,根据有限状态机返回的当前任务连接状态,更新两个连接池中相应入口的已打开连接数。
连接池创建模块在插件uxmpp加载阶段被调用。连接池管理模块,实时管理单worker节点和单用户连接池大小。对于一个新开始的任务,如果劝拿庞蜗菲教ㄗ⒉嵬净连接池中任务对应的入口表明连接数已达上限,暂缓该任务的执行。
实时执行器的基本流程是,依次遍历任务链表中的任务,把当前任务送至任务执行有限状态机,基于任务的当前状态做相应处理,根据处理结果更新任务状态。当所有任务均执行成功,或者当某个任务执行失败时,结束处理任务链表。下图中标记为黄色的模块修改实时执行器的任务处理过程,限制分布式查询同时打开的最大连接数。
用户通过执行SQL语句alter system set或者set的方式,修改参数的值。
表?8.1.?参数信息表
GUC名称 | 类型 | 含义 |
---|---|---|
uxmpp.realtime_pool | 布尔型 | 是否使用实时连接池方式 |
uxmpp. max_pool_size_per_worker | 整型 | 当启用实时连接池管理时,单worker的连接数上限,范围(1,0x7fffffff),默认值10 |
uxmpp.max_pool_size_per_user_per_worker | 整型 | 当启用实时连接池管理时,单用户的连接数上限。范围(1,0x7fffffff),默认值10 |
由于单worker连接池与单用户连接池均在共享内存中创建,因此插件uxmpp加载时,申请了一定大小的共享内存。
为了避免向连接池插入新记录时,共享内存耗尽引发异常,当前申请较大的共享内存空间。单worker连接池大小与可容纳的worker节点数(程序中设置为1024)成正比。单用户连接池大小与可容纳的worker节点数(程序中设置为1024),及用户个数(程序中设置为1024)成正比。
因此,单worker共享内存申请大小约为37464字节,大约为36K;单用户共享内存申请大小约为23081584字节,大约是22M。
uxmpp配置:
两台物理服务器:IP分别是192.168.2.246和192.168.2.249
Master节点:IP是192.168.2.246,端口5432。8个worker节点,分别是(以下表示形式是IP:端口):
192.168.2.246:5433
192.168.2.246:5434
192.168.2.246:5435
192.168.2.246:5436
192.168.2.249:5433
192.168.2.249:5434
192.168.2.249:5435
192.168.2.249:5436
3GUC参数设置:
uxmpp.shard_count 16
max_connections 4096
数据表
测试表使用uxbench创建的uxbench_branches表。
uxbench初始化,创建表:
[uxdb@localhost bin]$./uxbench -i
清空表中元组:
uxdb=# truncate uxbench_branches;
创建分布式表:
uxdb=#select create_distributed_table(‘uxbench_branches’,’bid’);
插入记录,共10000000条元组:
uxdb=# INSERT INTO uxbench_branches SELECT bid, (random()*100)::integer AS bbalance, ‘placeholder’ FROM generate_series(1, 10000000) AS bid;
uxbench使用的脚本test.sql,只包含一条SQL语句:
select * from uxbench_branches where bbalance=10;
编写脚本get_max_connections.sh,监测master节点(192.168.2.246)到worker节点所在的机器(192.168.2.249)上,状态为ESTALISHED的即时最大连接数。
修改GUC参数,关闭实时连接池:
uxdb=#alter system set uxmpp.realtime_pool to off;
重启master节点:
[uxdb@localhost bin]$./ux_ctl -D master_00 restart
执行uxbench,测试10分钟,客户端数为100:
[uxdb@localhost bin]$ ./uxbench -f test.sql -T 600 -c 100 &
执行脚本监测192.168.246到192.168.1.249上的所有已建立TCP连接数的即时最大值:
[uxdb@localhost bin]$ ./get_max_connections.sh -T 600 &
uxbench结果:
最大连接数检测结果:maximum number of connections is 603
IP为249的机器上共部署4个worker,因此,每个worker上同时建立的最大连接数为151。
令单worker上连接数的上限为上一小节测试值的四分之一,即40,再次检测单worker上已建立连接数的最大值。
打开开关,启用实时连接池:
uxdb=#alter system set uxmpp.realtime_pool to on;
设置单worker连接池大小:
uxdb=# alter system set uxmpp.max_pool_size_per_worker to 40; uxdb=# alter system set uxmpp.max_pool_size_per_user_per_worker to 100;
重启master节点:
[uxdb@localhost bin]$./ux_ctl -D master_00 restart
执行uxbench,共8小时,100个客户端:
[uxdb@localhost bin]$./uxbench -f test.sql -T 28800 -c 100 &
启动脚本,监测192.168.246到192.168.1.249上的所有已建立TCP连接数的即时最大值:
[uxdb@localhost bin]$./get_max_connections.sh -T 28800 &
uxbench执行结果:
最大连接数检测结果:maximum number of connections is 136
IP为249的机器上共部署4个worker,因此,每个worker上同时建立的最大连接数为34。
首先测试,只有uxdb用户进行查询,单用户的连接池上限设置为40。
打开开关,启用实时连接池:
uxdb=#alter system set uxmpp.realtime_pool to on;
设置单worker连接池大小:
uxdb=# alter system set uxmpp.max_pool_size_per_user_worker to 40; uxdb=# alter system set uxmpp.max_pool_size_per_worker to 100;
重启master节点:
[uxdb@localhost bin]$./ux_ctl -D master_00 restart
执行uxbench,共48小时,100个客户端:
[uxdb@localhost bin]$ ./uxbench -f test.sql -T 172800 -c 100 &
启动脚本,监测192.168.246到192.168.1.249上的所有已建立TCP连接数的即时最大值:
[uxdb@localhost bin]$ ./get_max_connections.sh -T 172800 &
uxbench执行结果:
最大连接数检测结果:maximum number of connections is 139
IP为249的机器上共部署4个worker,因此,每个worker上同时建立的最大连接数为35。