GaussDB(DWS)集群通信:详解pooler连接池
本文分享自华为云社区《GaussDB(DWS) 集群通信系列一:pooler连接池》,作者:半岛里有个小铁盒。
1.前言
适用版本:【8.1.0(及以上)】
GaussDB(DWS) 为MPP型分布式数据库,使用Share Nothing架构,数据分散存储在各个DN节点,而CN不存储数据,作为接收查询的入口,生成的计划会尽量下推到DN并行执行以提升性能,此过程中会产生大量的建连操作,使得通信开销变得很大。因此在大数据时代,集群规模越来越大,业务并发越来越高,数据库集群各节点间的通信压力也越来越大。GaussDB(DWS)集群通信技术,在大规模集群中可以承载高并发业务,能够实现高性能分布式通信系统。
2.背景
GaussDB(DWS) 中客户端执行查询流程如上图所示,其中具体的如下:
- 客户端向CN的监听端口发起连接;
- CN postmaster主线程accept连接,创建 postgres线程并将连接交给此线程处理;
- 客户端下发query到CN;
- CN的postgres线程将查询计划下发给其他 CN/DN,查询结果沿原路径返回到客户端;
- 客户端查询结束,关闭连接;
- CN上对应的postgres线程销毁退出;
CN与DN建连立流程,和客户端与CN建连立流 程基本相同。因此为了减少CN与DN建立连接,以及DN进程中postgres线程创建、销毁的开销,CN端实现了Pooler连接池。
3.Pooler连接池
如上图所示,CN的pooler连接池中会保存与其他CN/DN的连接,每一个连接在对端会对应一个postgres工作线程。
postgres工作线程是带状态属性的,如database,所以可以认为pooler连接池中的连接也是带属性的。不同属性间的连接是不能复用的,如上图所示,按不同属性切分为pool A/B/C等连接池。每个连接池中会存有连接往不同节点的空闲连接的数组,提供接口给外部使用或放入连接。
CN上的postgres工作线程在需要连接其他节点时,会创建一个本地agent,尝试从pooler连接池取跟本线程相同属性的空闲连接,pooler如果没有空闲连接,就会新建一个连接。连接交给agent后,可以视为线程私有。在线程退出时,agent才会将连接还给pooler。
接下来,我们从数据结构上来看看Pooler连接池实现原理:
空闲连接池
DatabasePool
/* All pools for specified database */ typedef struct databasepool { char *database; char *user_name; char *pgoptions; /* Connection options */ HTAB *nodePools; /* Hashtable of PGXCNodePool, one entry for each node */ MemoryContext mcxt; struct databasepool *next; /* Reference to next to organize linked list */ } DatabasePool; DatabasePool *databasePools = NULL;
进程级别数据结构
DatabasePool用于存储空闲连接,根据database,user_name,pgoptions三者来确定
如果通过三者查找到了,那么就取其中对应的nodePools,找不到则新加
nodePools中对应的数据结构为PGXCNodePool,用于存储本节点与其他每个cn/dn的连接,具体的保存如下
cn1[0,1,2,3,4,…]
dn1[0,1,2,3,4,…]
NodePool
typedef struct NodePool { Oid nodeoid; /* Hash key (must be first!) */ bool valid; ArrayLockFreeQueue pool; } PGXCNodePool;
进程级别数据结构
连接到某一节点的空闲连接的集合,通过无锁队列(数组)实现
从这里拿到对应的连接,直接复用
正在使用连接池
AgentPool
typedef struct { ArrayLockFreeQueue pool; AgentSlot* slots; }AgentPool;
进程级别的数据结构
存放一个进程中的所有的连接
其中slots为一个数组,表明一个槽位,与pool为一一对应的状态
用于保存所有线程持有的连接,即poolAgent数据结构
AgentSlot
typedef struct { int index; volatile AgentStatus status; PoolAgent* agent; }AgentSlot;
进程级别数据结构
存放进程中的某一个连接
index与AgentPool->pool相关联
status状态为,标识该连接是否正在使用/空闲/持有
agent中为某个线程的信息(也就是每个session),都是在全局数组poolAgents中保存的
PoolAgent
typedef struct { /* Agent members */ ThreadId pid; DatabasePool* pool; int index; /* param members */ char* user_name; char* pgoptions; char* paramsStr; char* localParams; /* params temporarily saved before commit */ char* tempNamespace; /* temp namespace name of session */ List* paramsList; /* save session params, for build paramsStr */ int paramsReady; /* param is set, need rebuild paramsStr */ /* Connection members */ int dnNum; int cnNum; PoolSlot** dnConn; PoolSlot** cnConn; NodeConnDef* cnDef; NodeConnDef* dnDef; /* handles members */ NodeHandle** dnHandles; NodeHandle** cnHandles; int dnUsed; int cnUsed; } PoolAgent;
对于每起一个线程session(即连接),都会有一个PoolAgent与之对应,即从DatabasePool->NodePool->pool取出来的连接
- cnDef、dnDef:初始化时从pgxc_node中拿到,即cn定义、端口、ip
- (session级别)dnConn、cnConn:从databasePools->nodePools-> pool拿真正对应的连接
- (query级别)dnHandles、cnHandles:从dnConn、cnConn里边dop出来使用,确保两者是一一对应的状态,当query结束时,只需要close handles就行,cnConn不需要close
Pooler连接池具体的复用流程如下:
- session需要连接时,通过DB+USER为key找到正确的pooler连接池,优先从中取走现有连接,如果连接池中没有连接的话,则新建连接;
- query结束后,CN的postgres线程并不会归还连接,连接可以用于当前session的下一个查询;
- session结束后,CN的postgres线程会将连接还到对应的pooler,连接对应的DN上的postgres线程并不会退出,处于ReadCommand中,等待复用后CN新的postgres线程发起任务;
4.Pooler连接池相关的视图
pg_pooler_status视图
pg_pooler_status视图记录了pooler连接池中的所有连接信息,每一行表示本CN发起的一个连接,对应对端进程的一个postgres线程
postgres=# select * from pg_pooler_status; database | user_name | tid | node_oid | node_name | in_use | node_port | fdsock | remote_pid | session_params ----------+-----------+-----+------------+--------------+--------+-----------+--------+-----------------+---------------- postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 94 | 140259241618584 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 101 | 140259241619432 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 91 | 140259241618160 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 95 | 140259241619008 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 59 | 140259241562192 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 106 | 140259241619856 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 108 | 140259241620280 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 117 | 140259241621128 | none postgres | user1 | | 2147483650 | datanode1 | f | 37110 | 114 | 140259241620704 | none
- in_use为‘t’表示这个连接正在某线程使用,为‘f’表示空闲连接等待复用
- tid列为本CN的持有此连接的线程号
- node_name列为对端进程号,remote_pid列为对端线线程号
- 在query_id为0或CN/DN不一致时,通过pooler视图查找CN与DN连接关系
一般pooler连接池中的连接会非常多,可以按不同字段group by查看某个db pool池中的连接情况,或连往某个node的连接情况,如:
select database,user_name,node_name,in_use,count(*) from pg_pooler_status group by 1, 2, 3 ,4 order by 5 desc limit 50;
5.Pooler连接清理
清理Session持有的连接
- cache_connection,是否使用pooler连接池缓存连接,默认开
- session_timeout,客户端连接空闲超时后报错退出归还连接
- enable_force_reuse_connections,事务结束后强制归还连接
- conn_recycle_timeout(8.2.1),CN空闲session超时后归还连接
Pooler空闲连接池中的连接
- pg_clean_free_conn视图/函数,清理1/4的空闲连接池连接,CM定期调用
- CLEAN CONNECTION语法,清理对应DB或user的所有空闲连接 clean connection to all for database postgres to USER user1;
6.总结
本文详细介绍了Libcomm通信库及其原理,让我们更好的理解GaussDB(DWS)集群通信中的具体逻辑,对于GaussDB通信运维也具备一定的参考意义。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
deepin Meetup·成都站全程回顾,干货满满,感动多多 | 附 PPT 下载
内容来源:deepin 社区 2024年3月9日,「deepin Meetup · 成都站」顺利举办!此次活动,我们聚集了业界专家与优秀的开发者,吸引了来自成都及周边地区 50 余名用户的积极参与。大家共同探讨deepin-IDE 成长历程、Flutter 跨平台应用程序开发等热门话题,同时,更有社区资深贡献者从社区参与的角度与大家分享回顾了 deepin 发展的三个历史时期。 接下来,就让我们一起回到精彩现场,看看此次都有哪些观点洞察和技术干货叭! 本次活动依然由 deepin(深度)社区主办,感谢 freeCodeCamp 成都社区提供支持。 deepin-IDE的成长脚步与未来道路 卢桢(deepin-mozart) / 中国发明协会成员,系统架构师 2023年9月,deepin-IDE 横空出世,受到了大家的广泛关注,来自 deepin-IDE 研发团队的卢桢为大家详细讲述了 deepin-IDE 从诞生以来打怪升级的故事,以及背后所用到的调试、迁移等核心技术,并岁deepin-IDE 的智能插件所提供的自动编码、代码注释及翻译等 AI 能力进行了现场演示。 值得一提的是,d...
- 下一篇
聊聊CWE 4.14 与 ISA/IEC 62443中,如何保障工业软件的安全性
本文分享自华为云社区《CWE 4.14 与 ISA/IEC 62443》,作者:Uncle_Tom。 1. 序言 随着 5G 的应用,物联的网发展,越来越多的自动化控制系统、云服务在工业控制系统被广泛使用。为了实现生产自动化,很多企业都引入了由 PLC(可编程逻辑控制器)控制的自动化生产设备和相关的自动化生产系统。用来连接各个自动化生产设备和生产系统的生产网络一般被称为 OT(Operation Technology)网络。而这些网络互联的普及与融合造成了 OT 环境系统安全受到威胁。再加上近来不断升温的政治冲突、恐怖主义与经济犯罪,这些都是引发面向产业关键基础设施进行攻击的动机。 2. CWE 4.14 在 28 年才能一遇的龙年 2 月 29 日,CWE 发布了新的一个版本 4.14。在这个版本发布的公告里,用了“其中包含了许多激动人心的更新(includes a number of exciting updates)”。这些更新主要包括: 有 4 个与硬件微架构相关的弱点; 1 个新视图:工业自动化和控制系统的CWE-1424:ISA/IEC 62443 要求解决的弱点视图; 对...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- 设置Eclipse缩进为4个空格,增强代码规范
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS7设置SWAP分区,小内存服务器的救世主
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7