RDMA over Commodity Ethernet at Scale (II)

3.  DSCP-BASEDPFC

在本小节中,我们测试了原始的基于VLAN的PFC面对的问题,并提出了基于DSCP的PFC方案。基于VLAN的PFC暂停帧中,VLAN TAG中包含了数据包优先级和VID,但是优先级和VID在部署中引发了两个严重的问题,因此提出了基于DSCP的PFC方案。

暂停帧是一个二层帧,并没有VLAN标签,数据包的VLAN标签有四部分,TPID被固定为0x8100,DEI(Drop Eligible Indicator丢弃符合条件的指标),PCP(Priority Code Point)包含数据包的优先级,VID(VLAN identifier)是数据包的VLAN ID。

尽管我们只需要PCP,但是PCP和VID是不可分离的,因此,为了支持PFC, 我们必须在服务器端和交换机端都配置VLAN。为了使得交换机端口支持VLAN,我们需要把面向交换机端口的服务器设置为trunk模式(支持VLAN标记的数据包),而不是access模式(发送和接收的都是没有标记的数据包)。基本的PFC功能都是使用这种配置,但是会引发两个问题。

第一,交换机的trunk模式和操作系统提供的服务有不利的交互。OS provisioning是一个基本服务,当服务器OS需要更新或者安装,或者当服务器需要被修复和供应的时候,需要运行这个基本服务。在我们的数据中心中,OS provisioning必须自动完成。我们使用PXE boot来安装OS。当服务器经过PXE boot的时候,它的NIC没有VLAN配置,结果就是不能发送和接收带有VLAN标签的数据包,但是由于面向服务器端口配置成了trunk模式,这些交换机端口只能发送带有VLAN标签的数据包,因此服务器之间的PXE boot通信和OS provisioning服务就崩溃了。我们尝试了一些“黑客”方式进行问题修复,比如基于猜测的服务器状态改变交换机端口配置,让NIC接收所有的数据包,不管是否有VLAN标签,但是这些方式都是很复杂并且不可靠的,或者说,都不是标准的。

第二,我们已经从二层VLAN移开了,我们所有的交换机,包括ToR,都运行着三层IP交付,而不是基于MAC的二层桥接。一个三层网络有很多优势,比如扩展性、更好的管理和监控、更好的安全性、所有的协议都是公开而标准的。但是,在三层网络中,当穿越子网边界时,没有标准的方式去预留VLAN PCP。

分析这两个问题,可以发现产生的原因都是,基于VLAN的PFC不必要的数据包优先级和VLANID,因此提出了基于DSCP的PFC,替换掉PCP和VID。我们的关键观点就是PFC暂停帧并不包含VLAN标签,数据包中的VLAN标签只是用来携带数据包优先级,但是在IP中,我们有更好的方式传输优先级信息,那就是IP头部的DSCP域。

解决办法就是把数据包优先级从VLAN标签中移到DSCP,这个改变是很小的,并且只涉及到了数据包(data packet)的格式,PFC暂停帧并没有改变。基于DSCP的PFC中,没有VLAN标签,所以就没有上述两个问题,因为上述两个问题的起因就是因为VLAN标签中的优先级和VLAN ID。面向服务器端口不用配置成trunk模式了,也就意味着PXE boot不会有任何问题。与此同时,数据包的优先级会以DSCP值的形式,在子网中通过IP路由正确传输。当然,基于DSCP的PFC并不能为工作在二层的设计提供服务,但是对我们来说也没任何问题,因为数据中心中没有二层网络。

DSCP值和PFC优先级的映射关系是灵活的,甚至可以多对一,本论文中,简单地将DSCP值i映射成了PFC优先级i。基于DSCP的PFC是公开可用的,并且所有的供应商都支持,我们坚信基于DSCP的PFC提供了一种比原始基于VLAN的策略更简单、扩展性更好的解决方案。

4.  TheSAFETY CHALLENGES

PFC和RDMA传输的应用带来了一些安全挑战,接下来就讲述一下遇到的挑战以及我们的解决方案。

4.1 RDMA传输活锁(livelock)

RDMA传输协议的设计有一个假设前提,就是在网络拥塞的时候,数据包不会被丢弃,在RoCEv2中是通过PFC来实现的,但是,丢包现象仍然会发生,比如FCS错误或者交换机软件、硬件层面的bug,理想情况下,我们希望RDMA性能在存在此类错误的情况下能够尽可能地不会损失太多。但是我们发现,即使丢包率很低,RDMA性能也会大幅下降。我们用下面简单的实验来说明这个问题。

用一台交换机W连接两个服务器A和B,分别进行RDMA SEND,WRITE,READ实验。第一个实验中,A执行RDMA SENDs将4MB数据以最快速度发送到B;第二个实验中,A执行RDMAWRITE操作,其余和第一个实验相同;第三个实验中,B使用RDMAREAD以最快的速度从B读取4MB数据块。实验环境中,丢包率是1/256(4%)。

我们发现,即使丢包率很低,吞吐能力还是为0。换句话说,系统处于活锁状态,虽然链路充分利用了线速,但是进程没有任何进展。根源在于go-back-0算法,这个算法用来进行RDMA传输的丢失恢复。假设A给B发送消息,这个消息被分段成了数据包0,1,…,m,假设数据包i丢失了,那么B会给A发送NAK(i),A收到之后就会从数据包0重新发送该消息,因此go-back-0就导致了活锁。一个4MB的消息被分成4000个数据包,因为丢包率是1/256,假设第一个256个数据包会丢失一个数据包,那么发送者就会重新发送,发送的时候又会丢包,所以会一直发送,但没有任何进展。表面上看起来一直在发送,但实际上并没有有效进展。

TCP和RDMA在网络上有不同的假设。TCP是最大努力交付,允许数据包丢失,并且通过诸如SACK等复杂的重传机制解决丢包问题。RDMA假设网络是无损的,因此供应商选择使用简单的go-back-0方法,在这种方法中,发送者不需要维护重传状态。

这个实验清晰地展示了在大规模网络环境中(比如我们的数据中心网络),尽管使用了PFC,但是仍然会有是丢包现象发生,因此还是需要一个复杂的重传机制。NIC的资源限制意味着无法实现像SACK那样复杂的重传机制,同时,SACK也没有必要,因为PFC已经消除了网络拥塞造成的丢包现象,丢包现象很少,没必要使用如此复杂的机制。

我们的解决办法是用go-back-N代替go-back-0机制,在go-back-N中,重传从第一个丢失的数据包开始,之前已经接收到的数据包不需要重传。Go-back-N机制几乎和go-back-0一样简单,同时避免了活锁。自从使用了go-back-N,我们没有遇到过活锁,因此建议使用go-back-N。

你可能感兴趣的:(项目,论文)