调研 RDMA 技术应用于 Redis 的杂乱笔记。


1. RDMA vs 传统计算机网络

传统计算机网络

传统的计算机网络收包流程如下图所示,可以发现:

  • 网络通信时,数据包每次至少需要复制 2 次
  • 以字节流传递,一条消息完整地传递至对端时,接收端可能会触发多次系统调用以读取完整地消息

network_recv_packets

RDMA

RDMA 是一种绕过远程主机操作系统内核直接访问其内存的技术。目前实现 RDMA 技术的网络协议有以下三种:

  • InfiniBand:支持 RDMA 的新一代网络协议。由于这是一种新的网络协议,因此需要支持该协议的网卡和交换机。
  • RoCE:RDMA over Ethernet network,允许在标准以太网上(交换机)使用 RDMA 技术的网络协议,需要网卡必须是支持 RoCE 的特殊网卡。
  • iWARP:RDMA over TCP,允许在标准以太网上(交换机)使用 RDMA 技术的网络协议,只不过网卡要求是支持 iWARP 的(如果使用 CPU offloads 的话),否则所有 iWARP 栈都可以在软件中实现,但失去了大部分 RDMA 的性能优势。

三种协议使用的 API (verbs) 是相同的。

rdma_protocols

我们以 InfiniBand 为例,InfiniBand 通过在应用程序之间创建 channel 连接 (故可称为 Channel I/O) 以提供 messaging service 进行通信,如下图所示:

  • Queue Pairs(QPs):指 channel 的端点,每个 QP 包含一个 Send Queue(SQ) 和一个 Receive Queue(RQ)
  • 通过将 QPs 映射为应用程序的虚拟内存空间,以实现应用程序直接访问 QPs
    • 由 HCA(Host Channel Adapter) 提供地址转换
  • InfiniBand 提供两种 transfer semantics 用于传递消息
    • channel semantic: SEND / RECEIVE
      • 接收方预先在自己的 RQ 中定义数据结构
      • 发送方无需知道接收方 RQ 中的数据结构,仅负责调用 SEND 发送消息
    • memory semantic: RDMA READ / RDMA WRITE
      • 接收方在自己的虚拟内存空间中注册一个 buffer,并将控制权交予发送方
      • 发送方通过调用 RDMA READRDMA WRITE 读写该 buffer

channel

可以发现,InfiniBand 通过将网络协议固化于硬件上,从而实现 RDMA 技术,其带来以下优势:

  • Zero copy:应用程序可以在没有网络软件栈参与的情况下执行数据传输,并且数据被直接发送至对端缓冲区,无需在网络层之间进行复制
  • Kernel bypass:应用程序可以直接在用户态执行数据传输,无需系统调用,从而无需执行上下文切换
  • No CPU involvement:应用程序可直接访问远程主机的内存而无需远程主机的 CPU 参与
  • Message based transactions:数据以消息的形式传输,而不是以字节流的形式,从而应用程序无需执行将字节流切分为不同消息的过程
  • Scatter/gather entries support:RDMA 原生支持分散/聚合,即读取多个内存缓冲区并将它们作为一个流发送,或接收一个流后将其写入多个内存缓冲区中

其中 zero copy 和 kernel bypass 是 RDMA 具有低延迟、高吞吐和降低 CPU 使用率特性的关键所在。

2. 应用 RDMA 技术

想在 Redis 中利用 RDMA 技术的优势,主要有以下两种方式:

  • 软件重构:使用 RDMA API 重构应用程序
    • 优点:可以结合 RDMA 网络的硬件特性,调整软硬件结构,从原语使用、数据流优化、协议设计等方面重新设计软件逻辑,从而充分发挥 RDMA 网络的硬件优势
    • 缺点:侵入式开发,后续跟随官方 Redis 的更新较为复杂,门槛较高 (在学了,在学了.jpg)
  • 简单的网络替换:启动应用程序时,加载 libvma 动态库
    • 优点:操作简单,无需修改应用程序,方便跟随官方 Redis 版本更新
    • 缺点:无法充分发挥 RDMA 网络性能

3. 测试结果

以下测试结果是在服务端加载 libvma 动态库的情况下测得:

  • 当客户端数量和数据量大小变化时,使用 RDMA 对 Redis 的吞吐量和延迟均有巨大的提升: ops 约为未使用 RDMA 的 2 倍,延迟约为 1/2.
  • 可以发现在客户端线程数增加时,虽然吞吐量和延迟的提升和不使用 Pipeline 场景类似,但是 p99/p100 Latency 在线程数增加时,使用 RDMA 时延迟值的增长较未使用 RDMA 更为缓慢
  • 但是在使用 Pipeline 的情况下,使用 RDMA 对 Redis 的性能提升不明显: 数值上无明显差异

4. 参考资料