写点什么

系列解读 SMC-R:融合 TCP 与 RDMA 的 SMC-R 通信(二)

  • 2022-04-24
  • 本文字数:5046 字

    阅读完需:约 17 分钟

系列解读 SMC-R:融合 TCP 与 RDMA 的 SMC-R 通信(二)

通过上一篇文章 《系列解读 SMC-R:透明无感提升云上 TCP 应用网络性能(一)》我们了解到,RDMA 相对于 TCP 具有旁路软件协议栈、卸载网络工作到硬件的特点,能有效增加网络带宽、降低网络时延与 CPU 负载。而内核网络协议 SMC-R 在利用 RDMA 技术的同时、又进一步完美兼容了 socket 接口,能够透明无感的为 TCP 应用带来网络性能提升。因此,龙蜥社区高性能网络 SIG 认为 SMC-R 将成为下一代数据中心内核协议的重要组成,对其进行了大量优化,并积极将这些优化回馈到上游 Linux 社区。


本篇文章作为 SMC-R 系列的第二篇,将聚焦一次完整的 SMC-R 通信流程。通过具体的建连、传输、销毁过程,使读者进一步体会到 SMC-R 是一个融合了通用 TCP 与高性能 RDMA 的 "hybrid" 解决方案。

通信流程


如前篇所述,使用 SMC-R 协议有两种方法。其一,是在应用程序中显式创建 AF_SMC 族的 socket;其二,是利用 LD_PRELOAD 或 ULP + eBPF 的方式透明的将应用程序中的 AF_INET 族 socket 替换为 AF_SMC 族 socket。


我们默认使用 SMC-R 通信的节点已经加载了 SMC 内核模块,并通过上述方式将应用程序运行在 SMC-R 协议上。接下来,我们以 first contact  (通信两端建立首个连接) 场景为例,介绍 SMC-R 通信流程。

确认对端能力


使用 SMC-R 通信时,我们首先需要确认对端是否同样支持 SMC-R 协议。因此,SMC-R 协议栈为应用程序创建 SMC 类型 socket (smc socket) 的同时,还会在内核创建并维护一个与之关联的 TCP 类型 socket (clcsock),并基于 clcsock 与对端建立起 TCP 连接。


(图/TCP 握手确认对端 SMC-R 能力)


在 TCP 连接三次握手中,使用 SMC-R 协议的一端发送的 SYN/ACK 中携带了特殊的 TCP 选项 (Kind = 254,Magic Number = 0xe2d4),用于表明自身支持 SMC-R。通过检查对端发送的 SYN/ACK,通信节点得知其 SMC-R 能力,进而决定是否继续使用 SMC-R 通信。


(图/三次握手携带特殊 TCP 选项[1])


(图/代表 SMC-R 的 TCP 选项)

协议回退


若在上述 TCP 握手过程中,通信两端其一表示无法支持 SMC-R,则进入协议回退 (fallback) 流程。

协议回退时,应用程序所持有的 fd 对应的 smc socket 将被替换为 clcsock。从此,应用程序将使用 TCP 协议通信,从而确保数据传输不会因为协议兼容问题而中断。


需要注意的是,协议回退仅发生在通信协商过程中,如前文提到的 TCP 握手阶段,或是下文提到的 SMC-R 建连阶段。为便于跟踪诊断,SMC-R 协议详细分类了潜在的回退可能,用户可以通过用户态工具 smc-tools 观测到协议回退事件及原因。


(图/smc-tools 观测回退现象)

建立 SMC-R 连接


若在 TCP 握手中,两端均表示支持 SMC-R,则进入 SMC-R 建连流程。SMC-R 连接的建立依赖 TCP 连接传递控制消息,这种控制消息被称为 Connection Layer Control (CLC) 消息。


(图/使用 CLC 消息建立 SMC-R 连接)


CLC 消息的主要职责是同步通信两端的 RDMA 资源以及共享内存等信息。使用 CLC 消息建立 SMC-R 连接的过程与 SSL 握手类似,主要包含 Proposal、Accept、Decline、Confirm 等语义。在建连过程中,若遇到不可恢复的异常 (如 RDMA 资源失效) 导致后续 SMC-R 通信无法继续,也将触发前文所述的协议回退流程。


(图/SMC-R 握手过程[1])


First contact 场景下,由于通信两端首次接触,两者间尚不存在使用 RDMA 通信的条件。所以,在建立首个 SMC-R 连接时,还将创建 SMC-R 通信所需的 RDMA 资源,建立 RDMA 链路,申请 RDMA 内存。


创建 RDMA 资源


SMC-R 建连初期,两端根据应用程序传递的 IP 地址在本地寻找可用 (如相同 Pnet ID) 的 RDMA 设备,并基于找到的设备创建必要的 RDMA 资源,包括 Queue Pair (QP),Completion Queue (CQ),Memory Region (MR),Protect Domain (PD) 等等。


其中,QP 与 CQ 是 RDMA 通信的基础,提供了一套 RDMA 使用者 (如 SMC 内核协议栈) 与 RDMA 设备 (RNIC) 之间的异步通信机制。


QP 本质是存放工作任务 (Work Request, WR) 的工作队列 (Work Queue, WQ)。负责发送任务的 WQ 称为 Send Queue (SQ),负责接收任务的 WQ 称为 Receive Queue (RQ),两者总是成对出现,称为 QP。用户将希望 RNIC 完成的任务打包为工作队列元素 (Work Queue Element, WQE),post 到 QP 中。RNIC 从 QP 中取出 WQE,完成 WQE 中定义的工作。


CQ 本质是存放工作完成信息 (Work Completion, WC) 的队列。RNIC 完成 WR 后,将完成信息打包为完成队列元素 (Completion Queue Element, CQE) 放入 CQ 中。用户从 CQ 中 poll 出 CQE,获悉 RNIC 已经完成某个 WR。


(图/)RDMA 工作队列模型)


建立 RDMA 链路


通信两端将已创建的 RDMA 资源通过 CLC 消息同步到对端,进而在两端之间建立起基于 RC (Reliable Connection) QP 的 RDMA 链路。SMC-R 中将这种点对点逻辑上的 RDMA 链路称为 SMC-R Link。一条 SMC-R Link 承载着多条 SMC-R 连接的数据流量。


(图/SMC Link)


若通信节点之间存在不止一对可用的 RNIC,则会建立不止一条 Link。这些 Link 在逻辑上组成一个小组,称为 SMC-R Link Group。


(图/SMC-R Link Group)


在 Linux 实现中,每个 Link Group 具备 1-3 条 Link,最多承载 255 条 SMC-R 连接。这些连接被均衡的关联到 Link Group 的某一 Link 上。应用程序通过 SMC-R 连接发送的数据将由关联的 Link (也即 RDMA 链路) 传输。


同一个 Link Group 中,所有的 Link 互相“平等”。这个“平等”体现在同一 Link Group 中的 Link 具备访问 Group 中所有 SMC-R 连接收发缓冲区 (下文提到的 sndbuf 与 RMB) 的权限,具备承载任意 SMC-R 连接数据流的能力。因此,当某一 Link 失效时 (如 RNIC down),关联此 Link 的所有连接可以迁移到同 Link Group 的另一条 Link 上。这使得 SMC-R 通信稳定可靠,具备一定的容灾能力。


SMC-R 中,Link (Group) 在 first contact 时创建,在最后一条 SMC-R 连接断开一段时间 (Linux 实现中为 10 mins) 后销毁,具备比连接更长的生命周期。First contact 之后创建的 SMC-R 连接都将尝试复用已有的 Link (Group)。这样的设计充分利用了已有的 RDMA 资源,避免了频繁创建与销毁带来的额外开销。


申请 RDMA 内存


SMC-R 协议栈为每条 SMC-R 连接分配了独属的收发缓冲区:sndbuf (发送缓冲区) 与 RMB (接收缓冲区,Remote Memory Buffer)。这是两片地址连续,长度在 16 KB ~ 512 KB 间的内核态 ring buffer。

(图/SMC-R 连接 ring buffer)


其中,sndbuf 用于存放连接待发送的数据,被注册为 DMA 内存。本地 RNIC 设备可以直接访问 sndbuf,从中取走有效负载 (payload)。而 RMB 用于存放远程节点 RNIC 写入的数据,即连接待接收的数据。由于需要被远程节点访问,因此 RMB 被注册为 RDMA 内存。


注册 RDMA 内存的过程称为 Memory Registration,主要完成以下操作:


  • 生成地址翻译表


RDMA 使用者 (如本地/远程 SMC-R 协议栈) 通常使用虚拟地址 (VA) 描述内存,而 RNIC 则通过物理地址 (PA) 寻址。RNIC 从 WQE 或数据包中取得数据 VA 后通过查表得到 PA,进而访问正确内存空间。因此 Memory Registration 首要任务就是形成目标内存的地址翻译表。


  • Pin 住内存


现代 OS 会置换暂不使用的内存数据,这将导致地址翻译表中的映射关系失效。因此,Memory Registration 会将目标内存 pin 住,锁定 VA-to-PA 映射关系。


  • 限制内存访问权限


为避免内存非法访问,Memory Registration 会为目标内存生成两把内存密钥:Local Key (l_key) 和 Remote Key (r_key)。内存密钥实质是一串序列,本地或远端凭借  l_key 或 r_key 访问 RDMA 内存,确保内存访问合法。


SMC-R 中,远程节点访问本地 RMB 所需的 addr 与 r_key 被封装为远程访问令牌 (Remote Token, rtoken),通过 CLC 消息传递到远端,使其具备远程访问本地 RMB 的权限。


SMC-R 连接销毁后,对应的 sndbuf 与 RMB 将被回收到 Link Group 维护的内存池中,供后续新连接复用,以此减小 RDMA 内存创建/销毁对建连性能的影响。


(图/sndbuf / RMB 内存池)

验证 SMC-R Link


由于 first contact 场景下新建立的 SMC-R Link 尚未经过验证,所以在正式使用 Link 传输应用数据前,通信两端会基于 Link 发送 Link Layer Control (LLC) 消息,用于检验 Link 是否可用。


(图/使用 LLC 消息确认 SMC Link 可用)


LLC 消息通常为请求-回复模式,用于传输 Link 层面的控制信息,如添加/删除/确认 Link,确认/删除 r_key 等。


(图/LLC 消息请求-回复模式)


类型
说明
ADD_LINK
向 Link Group 中添加新的 Link。
CONFIRM_LINK
确认新创建的 Link 是否能够正常工作。
DELETE_LINK
删除一个特定的 Link 或整个 Link Group。
CONFIRM_RKEY
新增 RMB 时通知 Link 对端。
DELETE_RKEY
删除一个或多个 RMB 时通知 Link 对端。
TEST_LINK
确认 Link 是否健康、活跃。

(表/典型 LLC 消息含义)


LLC 消息的传输基于 RDMA 的 SEND 操作完成,与之相对的是后文提到的 RDMA WRITE 操作。


(图/SEND 操作)


SEND 操作又被称为“双边操作”,这是因为 SEND 操作要通信两端都参与进来。一次 SEND 的传输过程为:


  • 接收端 RDMA 使用者 (SMC-R 内核协议栈) 向本地 RQ 中 Post RWQE,RWQE 中记录了待接收数据的长度以及预留内存地址;

  • 发送端 RDMA 使用者 (SMC-R 内核协议栈) 向本地 SQ 中 Post SWQE,SWQE 中记录了待发送数据长度和内存地址。发送端 RNIC 根据 SWQE 记录的信息取出相应长度的数据发送到对端;

  • 接收端 RNIC 接收到数据后,取出 RQ 中的第一个 RWQE,依照其中记录的内存地址和长度存放数据。


通过在 Link 上收发 CONFIRM_LINK 类型的 LLC 消息,通信两端确认了新创建的 Link 具备 RDMA 通信的能力,可以用于传输 SMC-R 连接数据。

基于共享内存通信


通过上述重重步骤,first contact 场景下 SMC-R 建连工作终于结束。接下来,应用程序将通过已建立好的 SMC-R 连接传输数据。


(图/基于 RDMA 共享内存通信)


应用程序下发到 SMC-R 连接中的数据由关联的 Link 通过 RDMA WRITE 操作写入远程节点 RMB 中。


(图/RDMA WRITE 操作)


与上文提到的 SEND 操作不同,RDMA WRITE 又被称为“单边操作”。这是因为数据传输只有 RDMA WRITE 发起的一方参与,而接收数据一方的 RDMA 使用者完全不参与数据传输,也不知晓数据的到来。一次 RDMA WRITE 操作过程如下:


  • 前期准备阶段,接收端 RDMA 使用者 (SMC-R 内核协议栈) 将接收缓冲区注册为 RDMA 内存,将远程访问密钥 rkey 告知发送端,使其拥有直接访问接收端内存的权限,这个过程我们在前文介绍过。

  • 发送端 RDMA 使用者 (SMC-R 内核协议栈) 向 SQ 中 post SWQE。与 SEND 不同的是,RDMA WRITE 的 SWQE 中不仅包含数据在本地的内存地址和长度,还包含数据即将存放在接收端的内存地址,以及访问接收端内存所需的 r_key。发送端 RNIC 根据 SWQE 中记录的信息将数据传输到接收端。

  • 接收端 RNIC 核实数据包中的 r_key,将数据存放到指定内存地址中。此时的接收端 RDMA 使用者并不知道数据已经被写入内存。


由于 RDMA WRITE 操作不需要接收端 RDMA 使用者参与,因此非常适合大量数据的直接写入。不过,由于接收端并不知晓数据到来,发送端写入数据后需要通过 SEND 操作发送控制消息通知接收端。在 SMC-R 中,这种控制消息称为 Connection Data Control (CDC) 消息。CDC 消息中包含 RMB 相关控制信息用以同步数据读写。


内容
含义
Sequence number
CDC 消息序列号
Alert token
发送此消息的 SMC-R 连接 ID
Producer cursor
RMB 数据生产游标 (写者更新)
Producer cursor wrap seqno
RMB 数据生产 wrap 次数 (写者更新)
Consumer cursor wrap seqno
RMB 数据消费wrap 次数 (读者更新)
Consumer cursor
RMB 数据消费 游标 (读者更新)

(表/CDC 消息主要内容)


在系列文章的第一篇中我们提到,SMC-R 名称中的“共享内存”指的是接收端的 RMB。结合上述的 RDMA WRITE 操作与 CDC 消息,SMC-R 的共享内存通信流程可以总结为:


(图/共享内存通信细节)


  • 发送端的数据通过 socket 接口,由应用缓冲区拷贝至内核 sndbuf 中 (图中未画出 sndbuf)

  • 协议栈通过 RDMA WRITE 单边操作将数据写入接收端 RMB 中

  • 发送端通过 SEND 双边操作发送 CDC 消息告知接收端有新的数据到来

  • 接收端从 RMB 中拷贝数据至应用缓冲区

  • 接收端通过 SEND 双边操作发送 CDC 消息告知发送端 RMB 中部分数据已被使用

连接关闭与资源销毁


结束数据传输后,主动关闭方发起 SMC-R 连接关闭流程。与 TCP 相似,SMC-R 连接也存在半关闭/全关闭状态。断开的 SMC-R 连接与 Link (Group) 解绑,相关的 sndbuf 与 RMB 也将被回收到内存池中,等待复用。同时,与 SMC-R 连接关联的 TCP 连接也进入关闭流程,最终释放。


若 Link (Group) 中不再存在活跃的 SMC-R 连接,则等待一段时间后 (Linux 实现中为 10 mins) 进入 Link (Group) 销毁流程。销毁 Link (Group) 将释放与之相关的所有 RDMA 资源,包括 QP、CQ、PD、MR、以及所有的 sndbuf 与 RMB。Link (Group) 销毁后,再次创建 SMC-R 连接则需要重新经历 first contact 流程。

总结


本篇作为 SMC-R 系列文章的第二篇,以 first contact 场景为例,介绍了完整的 SMC-R 通信流程。


包括:通过 TCP 握手确认对端 SMC-R 能力;使用 TCP 连接传递 CLC 消息,交换 RDMA 资源、创建 RDMA 链路、建立 SMC-R 连接;通过 RDMA SEND 操作发送 LLC 消息验证 Link 可用;基于 Link 使用 RDMA WRITE 传输应用程序数据,并利用 CDC 消息同步 RMB 中数据变化;关闭 SMC-R、TCP 连接,销毁 RDMA 资源等一系列过程。


上述过程充分体现了 SMC-R 的 "hybrid" 特点。SMC-R 既利用了 TCP 的通用性 ,如通过 TCP 连接确认对端能力,建立 SMC-R 连接与 RDMA 链路;又利用了 RDMA 的高性能 ,如通过 Link 传输应用程序数据流量。正因为如此,SMC-R 能够在兼容现有 TCP/IP 生态系统关键功能的同时为 TCP 应用提供透明无感的网络性能提升。


参考链接:

[1] https://datatracker.ietf.org/doc/html/rfc7609

2022-04-24 15:172521

评论 1 条评论

发布
用户头像
这是阿里那个么
2022-04-27 17:44
回复
没有更多了
发现更多内容

首发|Clusterpedia 0.1.0 四大重要功能

Daocloud 道客

开源项目 多云管理 K8s 多集群管理 多云资源复杂检索

会声会影2022脸部索引功能详解

懒得勤快

一文全面掌握大数据关联与汇聚

云智慧AIOps社区

redis Clickhouse flink sql 大数据开发

《隐私计算》重磅发布,全面、系统论述数据要素安全流通价值

博文视点Broadview

《重构 JavaScript》读后感和部分摘录

道道里

前端 测试 重构

Kafka中指定副本为Leader的三种实现方式

石臻臻的杂货铺

kafka 运维

智汇华云 | Kubernetes多集群管理方案kubefed原理解析

华云数据

云计算 华云数据 虚拟云

数仓中长跳转问题复现及解决方案

华为云开发者联盟

寄存器 GaussDB(DWS) 长跳转 编译器O2

【C语言】一篇速通操作符

謓泽

C语言 操作符 3月月更

2022年1月娱乐直播行业用户洞察:行业格局稳定,内容运营精细化

易观分析

java培训:MyBatis的架构与原理分析

@零度

mybatis JAVA开发

EMQ 正式成为 OASIS 最高级别成员,主导推进物联网协议标准化应用

EMQ映云科技

开源 物联网 ibm mqtt OASIS

始于信任 忠于专业|DataPipeline收到一封来自山东城商行联盟的感谢信

DataPipeline数见科技

混合云管平台排名您知道吗?看这里!

行云管家

混合云 云管

从Nacos到完全自研|得物的注册中心演进之路

得物技术

架构 raft 注册中心 实例 兼容性测试

Tuxera2022mac读写硬盘U盘工具

茶色酒

Tuxera2022

云原生网络利器--Cilium 总览

Daocloud 道客

ebpf cilium 云原生网络 容器网络方案

web前端培训:Vue3 调度系统的深度剖析

@零度

Vue 前端开发

如何获取 Docker 容器的 IP 地址

AlwaysBeta

Docker 容器

脱颖而出!OceanBase 入选 2021“科创中国”开源创新榜单

OceanBase 数据库

数据库 分布式 OceanBase 开源 科创中国

大数据培训:Spark高频面试题汇总

@零度

大数据 spark

微服务身份认证需求下的私钥托管痛点与破局

全象云低代码

微服务 低代码 身份认证 鉴权 密钥

Camtasia Studio2022激活码序列号

茶色酒

Camtasia Studio2022

高性能图计算系统 Plato 在 Nebula Graph 中的实践

NebulaGraph

图数据库 图计算 分布式图数据库

IOS技术分享| anyLive 开源项目

anyRTC开发者

ios 音视频 移动开发 视频直播 开源demo

DM 中 relay log 性能优化实践丨TiDB 工具分享

PingCAP

Web 键盘输入法应用开发指南 (3) —— 输入法事件

天择

JavaScript 键盘 输入法 3月月更

2022年数据库审计厂家就选行云管家!功能强大!

行云管家

数据库 网络安全 数据库审计

2022年的SaaS行业,钱往哪里去?

ToB行业头条

2022,你的团队距离持续部署还有多远?| 研发效能提升36计

阿里云云效

阿里云 云原生 持续部署 研发团队 研发

上手体验!如何借助龙蜥实验室快速部署 Web 应用?

OpenAnolis小助手

开源 国产操作系统 web服务器

系列解读 SMC-R:融合 TCP 与 RDMA 的 SMC-R 通信(二)_文化 & 方法_龙蜥社区高性能网络SIG_InfoQ精选文章