GaussDB(DWS)通信库libpq重构介绍(二)

举报
c.j 发表于 2021/08/31 15:34:39 2021/08/31
【摘要】 1. Poller锁优化详细设计1.1外部接口介绍CleanConnection、pg_pooler_status、pv_total_memory_detail、pgxc_pool_reload、pg_pool_validate等pooler相关函数视图在内部实现上均有修改,但未修改接口对外表征及具体语义。1.2  空闲连接的无锁存取数据结构设计图 1‑1 空闲连接存储数据结构(优化前)图 ...

1. Poller锁优化详细设计

1.1外部接口介绍

CleanConnectionpg_pooler_statuspv_total_memory_detailpgxc_pool_reloadpg_pool_validatepooler相关函数视图在内部实现上均有修改,但未修改接口对外表征及具体语义。

1.2  空闲连接的无锁存取

数据结构设计


图 11 空闲连接存储数据结构(优化前)


图 12 空闲连接数组的存入(优化前,需加锁)


图 13 空闲连接数组的取出(优化前,需加锁)

如上方图片所示,优化前空闲连接的总数据结构是,不同的DB属性DBPool组成的全局DBPool List,不同DB间的连接不能复用。

每个DBPool拥有一个存储DN节点个数NodePoolHash表,用来存储连往不同DN的空闲连接。

每个NodePool拥有一个slot指针数组,前面的freeSize是有效的连接。slot连接的取还都是加锁后操作最后一个非空指针实现的。

优化前需要加锁的位置:

  • DBPool List的查找、遍历、新增(代码未实现删除操作)。
  • NodePool Hash的查找、遍历、新增、删除(LW_EXCLUSIVE)。
  • Slots数组的新增、删除、遍历。

图 14 空闲连接存储数据结构(优化后)

       无锁ringbuffer介绍,从readmax_read为可读区域,从max_readwrite为正在写入但还未完全写好的区域,从writeread为可写区域,三个index数组下标的操作需为CAS操作,支持并发读写。

       如上方图片所示,优化后的修改主要是将存储空闲连接的slot指针数组修改为无锁ringbuffer

       优化后去除加锁的位置:

  • DBPool List的查找,遍历不加锁,新增保留加锁,不实现删除。(在不free list item的前提下可实现新增不加锁。不删除dropDB如果影响性能,可以考虑挪到List尾的方式保留内存,不影响查找效率。)
  • NodePool Hash的查找、遍历加LW_SHARED锁,新增加LW_EXCLUSIVE锁,为了保证无锁查找不做删除操作。新增仅在增删节点时使用,遍历只在视图函数中使用,不影响普通场景下查询性能。
  • Slots的新增、删除、遍历(使用对无锁队列先poppush的方法)。

2. Agent index的无锁存取

数据结构设计


46 Agent连接存储数据结构(优化前)

如上方图片所示,优化前使用中的连接(以下称Agent连接)存储在每个线程自己的poolAgent数据结构中,因为遍历所有poolAgent的需求,每个线程又会把自己的poolAgent指针挂到全局的poolAgents指针数组。

优化前需要加锁的位置:

  • 工作线程将agent指针在全局数组的存入和取出。
  • 工作线程将某个节连接存入Conn*指针数组。
  • 视图函数对全局poolAgents数组的遍历及对某个agent的读取。


47 Agent连接存储数据结构(优化后)

如上方图片所示,优化后的修改点如下:

  • 使用无锁ringbuffer保存可用的agent index,并发存取index不再需要加锁。
  • poolAgents全局数组中每个元素除了原有的agent指针外,增加status标志,状态为RUN时,保证agent指针内存是可读的,此时其他视图函数线程可CAS修改为HOLD状态,agent此时将无法修改为idle状态,内存不会被释放,实现无锁并发读。
  • Conn*指针会随时free,无法实现无锁并行读。agentConn*连接指针中保存的socketremotePid信息,复制一份存入ConnDefConnDefagent整体一起malloc/free,在RUN状态时,此部分内存是实时可读的。

优化后去除加锁的位置:

  • agent index的并发存取。
  • Conn*指针数组不再会被其他线程并发读,可以视为thread local变量,无需加锁。
  • agent数组的遍历及单个agent中部分元素的并发读(需HOLD状态读保护)。

想了解GuassDB(DWS)更多信息,欢迎微信搜索“GaussDB DWS”关注微信公众号,和您分享最新最全的PB级数仓黑科技,后台还可获取众多学习资料~

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。