写点什么

Libcomm 通信库:GaussDB(DWS) 为解决建联过多的小妙招

  • 2024-03-12
    广东
  • 本文字数:3935 字

    阅读完需:约 13 分钟

Libcomm通信库:GaussDB(DWS) 为解决建联过多的小妙招

本文分享自华为云社区《GaussDB(DWS) 集群通信系列三:Libcomm通信库》,作者: 半岛里有个小铁盒。

1.前言


适用版本:【8.1.0(及以上)】


在大规模集群、高并发业务下,如果有 1000DN 集群,每个 stream 线程需要建立 1000 个连接。如果 1000 stream 并发,DN 总共需要建立 100 万个连接,会消耗大量的连接、内存、fd 资源。为了解决这个问题,我们引入了 Libcomm 通信库,在一个物理长连接上模拟 n 个逻辑连接,使得所有并发的数据跑在一个物理连接上,极大的解决了物理连接数过多和建连耗时的问题。

2.基本原理


GaussDB(DWS)为解决建联过多的问题,实现了 Libcomm 通信库(即逻辑连接通信库),在一个物理长连接上模拟 n 个逻辑连接,使得所有并发的数据跑在一个物理连接上。比如 DN1 需要给 DN2 发送数据,并发数 1000,在原有逻辑下,DN1 需要建立与 DN2 连接的 1000 个线程与之进行交互,消耗了大量的连接、内存、fd 资源,而改造 Libcomm 通信库之后,DN1 与 DN2 仅需建立一个真正的物理连接,在这个物理连接上可以建立很多个逻辑链接,这样可以使得 1000 个并发就可以用同一个物理连接进行数据交互。


那么 GaussDB(DWS)的逻辑连接是怎么实现的呢?首先我们从连接数据流入手,挖掘其实现逻辑。


物理连接支持 TCP、RDMA 等协议连接,以 TCP 为例,其物理连接数据流可以分为两部分,即数据包头+数据。数据包头为固定长度,其中包含逻辑连接号和数据块长度,用来区别逻辑连接,并接收每个连接各自对应的数据。



了解了物理连接发送的数据流,那具体的发送逻辑是什么样的呢?其具体的流程如下图所示:



上图中 producer 线程为发送线程,consumer 线程为接收线程,发送端逻辑如下:


  1. send queue:producer 发送线程将要发送的数据先 push 到一个无锁队列中,push 完成之后,producer 线程就可以继续做自己的事情了

  2. send proxy thread:通信存在一个发送端代理线程,会统一将无锁队列中的数据,通过物理连接发送到对端


接收端逻辑如下:


  1. receive proxy thread:通信存在一个接收端代理线程,会统一将无锁队列中的数据,通过物理连接接收回来,解析数据包头之后,放到对应线程的 buffer 池中

  2. buffer1:consumer 接收线程会从自己对应的 buffer 池中取出数据,执行自己的数据加工逻辑。


上述这个方法可能会存在一些问题,并发比较高时 producer 线程会一直往队列里 push,如果此时对端 cunsumer1 线程正在处理别的数据导致接收 buffer1 满了的话,producer2 和 producer3 无法往网络上填充更多的数据,发送阶段就会阻塞,而此时可能 consumer2 和 consumer3 正在空闲状态,等待这个接收数据,但是因为发送端阻塞而接收不到,这种场景会严重影响性能。这个模型我们称之为 push 模型。因此我们需要通过另外一种流控机制来解决这个问题,我们称之为 pull 模型。


  • push 模型:发送端不感知接收端状态。一直往无锁队列中 push,直到 push 阻塞。

  • poll 模型:发送端感知接收端状态。发送端一开始不会发送数据,当接收端里的 buffer 池内存满足一定条件时,通知对应的发送端,并告知可以接收的数据量,发送端可以按照对端可以接收的数据量进行发送。


通过 poll 模型的实现,在本线程阻塞的情况下,其他的线程不会阻塞,以确保物理连接中数据永远不会阻塞,保证连接的通畅性。

3.相关视图

3.1.pgxc_comm_delay


该视图展示所有 DN 的通信库时延状态。


该视图中的字段包括节点名称、连接对端节点的节点名称、连接对端 IP 的对端地址、当前物理连接使用的 stream 逻辑连接数量、当前物理连接一分钟内探测到的最小时延、当前物理连接一分钟内探测道德平均值和当前物理连接一分钟内探测到的最大时延。


3.2.pgxc_comm_recv_stream


该视图展示所有 DN 上的通信库接收流状态。其中字段包括节点名称、使用此通信流的线程 ID、连接对端节点名称、连接对端节点 ID、通信对端 DN 在本 DN 内的标识编号、通信流在物理连接中的标识编号、通信流所使用的 tpc 通信 socket、通信流当前的状态、通信流对应的 debug_query_id 编号、通信流所执行查询的 plan_node_id 编号、通信流所执行查询 send 端的 smpid 编号、通信流所执行查询 recv 端的 smpid 编号、通信流接收的数据总量、通信流当前生命周期使用时长、通信流的平均接收速率、通信流当前的通信配额值、通信流当前缓存的数据大小。


3.3.pgxc_comm_send_stream


该视图展示所有 DN 上的通信库发送流状态。其中字段包括节点名称、使用此通信流的线程 ID、连接对端节点名称、连接对端节点 ID、通信对端 DN 在本 DN 内的标识编号、通信流在物理连接中的标识编号、通信流所使用的 tpc 通信 socket、通信流当前的状态、通信流对应的 debug_query_id 编号、通信流所执行查询的 plan_node_id 编号、通信流所执行查询 send 端的 smpid 编号、通信流所执行查询 recv 端的 smpid 编号、通信流接收的数据总量、通信流当前生命周期使用时长、通信流的平均接收速率、通信流当前的通信配额值和通信流等待 quota 值产生的额外时间开销。


3.4.pgxc_comm_status


该视图展示所有 DN 的通信库状态。其中字段包括节点名称、节点通信库接收速率,单位为 byte/s、节点通信库发送速率,单位为 byte/s、节点通信库接收速率,单位为 Kbyte/s、节点通信库发送速率,单位为 Kbyte/s、cmailbox 的 buffer 大小、libcomm 进程通信内存的大小、libpq 进程通信内存的大小、postmaster 线程实时使用率、gs_sender_flow_controller 线程实时使用率、gs_receiver_flow_controller 线程实时使用率、多个 gs_receivers_loop 线程中最高的实时使用率、当前使用的逻辑连接总数。


4.相关 GUC 参数

4.1 comm_max_datanode


表示 TCP 代理通信库支持的最大 DN 数,最小值为 1,最大值为 8192。当 DN 数小于 256 时,默认值为 256;否则,为大于等于 DN 数的 2 的 N 次方。在集群扩容、缩容场景下,要注意此参数的变更。

4.2 comm_max_stream


表示 TCP 代理通信库支持的最大并发 stream 数量,默认值为 1024,最大为 60000,此参数要保证大于并发数


每并发平均 stream 算子数


(smp 的平方),否则会报错 Cannot get stream index, maybe comm_max_stream is not enough。此外,在设置此参数时需要考虑占用内存问题,其大小为 256byte * comm_max_stream * comm_max_datanode,可见在内存、comm_max_datanode 和 comm_max_stream 三者之间需要一个动态的规划。


针对 comm_max_stream 不足问题,可以考虑三种解决方案:


新版本直接使用 pgxc_comm_status 视图查看 DN 的 stream 使用情况:select node_name, stream from pgxc_comm_status order by 2 desc;



在 CN 上查询当前任意两个 DN 之间的 stream 情况:select node_name, remote_name, count(*) as stream from pgxc_comm_send_stream group by 1, 2 order by 3 desc limit 30;



若当前业务恢复, 可使用脚本对 stream 进行监控;


然而,还有情况是个别的 SQL 语句严重消耗 stream,此时可以使用实时 topsql 或历史 topsql 找到对应的语句,修改以解决问题。

4.3 comm_max_receiver


表示 TCP 代理通信库接收端接收线程的数量,最大值为 50,默认值为 4。在大集群、大并发场景下,适当的调大该参数有利于提升查询的性能;但如果通信层可用内存不足,线程间有竞争会对接收性能有负面影响。


注:SMP 是指对称多处理技术,数据库领域的 SMP 并行技术一般指利用多线程技术实现查询的并行执行,以充分利用 CPU 资源,从而提升查询性能。SMP 特性通过算子并行来提升性能,同时会占用更多的系统资源,在使用时,需要根据使用场景与限制进行合理的配置。在 GaussDB 中,SMP 功能由 query_dop 参数决定,默认值为 1。

4.4 comm_cn_dn_logic_conn


对于 256 节点的集群来说,并发场景导致 CN 和 DN 之间存在大量连接,每个连接占用一个端口,则 CN 的端口号很容易受限。为解决此问题,设计了 CN 多流,即 CN 与 DN 之间采用逻辑连接。comm_cn_dn_logic_conn 参数默认值是 off,在集群规模或并发达到一定程度时,需要将其开启为 on,避免 CN 与 DN 之间由于端口号受限而无法建连。

4.5 comm_quota_size


TCP 代理通信库采用 pull 模式进行流量控制,避免消息堵塞。两个 DN 分别有一个 buffer,当一条通道发送端数据量过大时,很容易造成 buffer 填满,阻塞了其他通道的发送。此时,对于每条通道设置一个 quota,接收端根据 buffer 剩余空间的大小发送给发送端一个合理 quota 值,发送端根据 quota 大小发送数据。


comm_quota_size 表示每个通道单次不间断发送数据量配额,默认值 1MB。当通道发送数据量达到配额时,发送端等待接收端重新发送配额,进而继续发送数据,从而实现流控功能。其取值为 0 时,表示不使用 quota,在一些大流量等场景中,查询之间可能会有影响。在 1GE 网卡环境中,受网卡能力限制,应该调小该参数,推荐 20KB~40KB。如果环境内存充足,参数 comm_usable_memory 设置较大,可以适当调大,从而提升性能。

4.6 comm_usable_memory


commusable_memory 表示的是 TCP 代理通信库可使用的最大内存大小,默认值 4000MB。此参数需要根据环境内存及部署方式具体配置,保证了系统不会因为通信层接收缓存造成进程内存膨胀。在单台机器上,通信占用内存最坏情况=部署节点个数* comm_usable_memory。考虑环境内存情况,此参数配置过小,会影响通信性能,过大则可能造成系统内存不足等问题。与 comm_quota_size 结合,进行合理的配置至关重要。

5.总结


本文详细介绍了 Libcomm 通信库及其原理,让我们更好的理解 GaussDB(DWS)集群通信中的具体逻辑,对于 GaussDB(DWS)通信运维也具备一定的参考意义。

6.参考连接


  1. GaussDB 重要通信参数汇总:https://bbs.huaweicloud.com/blogs/239863

  2. 【带你走进 DWS 大集群内幕】大集群通信:作业 hang、残留问题定位:https://bbs.huaweicloud.com/blogs/407719

  3. GaussDB(DWS) 集群通信系列三:集群通信常用视图:https://bbs.huaweicloud.com/blogs/209112

  4. GaussDB(DWS)通信库 libpq 重构介绍(一):https://bbs.huaweicloud.com/blogs/289336

  5. GaussDB(DWS)通信库 libpq 重构介绍(二):https://bbs.huaweicloud.com/blogs/297955


点击关注,第一时间了解华为云新鲜技术~

发布于: 7 小时前阅读数: 17
用户头像

提供全面深入的云计算技术干货 2020-07-14 加入

生于云,长于云,让开发者成为决定性力量

评论

发布
暂无评论
Libcomm通信库:GaussDB(DWS) 为解决建联过多的小妙招_数据库_华为云开发者联盟_InfoQ写作社区