问题9:如何多流?是多个通道同时发送head+data吗?
解:一个流发送完整的数据 。 多流是并发 。
TCP代理通信库的发送端实现 , producerA和producerB分别给DN1发送数据 , 为保证发送端head+data发送的完整性 , producerA首先需要对单个物理连加锁 , 此时producerB处于等锁状态 , producerA将数据完整发送到本地协议栈后返回 , 并释放锁 , producerB获得锁后发送数据 。 节点数越多冲突越少 。

文章插图
问题10:加锁等待是否影响效率?SCTP的实现也是如此?
解:不影响 , 因为有缓存buffer 。
【通信原理知识点总结 MPPDB通信库发展历程】

文章插图
问题11:数据丢失 , 永远无法达到head怎么办?一直缓存?
解:不会丢失 , TCP协议有保证 。
CN多流实现
在V1R8C00版本中 , CN和DN之间的链接使用libcomm通信库 , 即两个节点间仅存在一条物理通道 , 在该物理通道上使用逻辑连接通道实现并行通信 。
1、CN端流程:
- 建立连接:CN调用Libcomm的gs_connect与DN建立连接 , 入参中指明建立双向逻辑通道 , 使用相同的nidx , sidx同时初始化发送和接受的mailbox , 通过发送流控线程通知接收端;
- 等待DN返回结果:通过判断发送mailbox的状态 , 确认DN端已成功建立的逻辑连接(发送流控线程收到DN端的CTRL_READY报文);
- 发送startuppacket:通过PQbuildPGconn , 初始化libpq的pg_conn结构体 , 生成startuppacket , 随后通过gs_send发送startuppacket给DN端;
- 等待DN PG线程初始化:通过LIBCOMMgetResult , 等待DN端返回ready for query报文 , 之后认为连接建立成功 。
- 初始化发送、接收mailbox:DN端接收流控线程识别到连接请求来自CN后 , 调用gs_build_reply_conntion , 注册CN的信息 , 初始化发送mailbox , 随后初始化接收mailbox , 最终通过流控线程返回CTRL_READY报文 , 表示逻辑通道建立成功;
- 创建unix domain sock:DN端接收流控线程 , 创建一个unix domain sock , 将生成的逻辑连接地址通过该通道发给postmaster主线程;
- fork postgres子线程:postmaster主线程的serverloop监听到unix domain sock后 , 接收逻辑连接地址 , 保存到port结构体中 , 随后fork postgres子线程(沿用原有逻辑);
- postgres线程初始化完毕:在pg线程完成初始化后 , 首先给CN回复ready for query报文 , 随后进入ReadCommand函数 , 等待CN发来的下一个Query 。

文章插图
本文分享自华为云社区《GaussDB通信原理总结》 , 原文作者:Caesar.D 发 。
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
