本文是阿里2021年SIGCOMM的重磅论文,详细介绍了阿里基于Barefoot的Tofino硬件可编程交换机实现的“洛神”XGW-H高性能网关,其性能比XGW-x86:
- XGW-H的吞吐量是XGW-x86的20倍以上;
- XGW-H的包速率是XGW-x86的72倍;
- XGW-H的平均时延比XGW-x86低95%。
参考文献
Tian Pan, Nianbing Yu, Chenhao Jia, Jianwen Pi, Liang Xu, Yisong Qiao, Zhiguo Li, Kun Liu, Jie Lu, Jianyuan Lu, Enge Song, Jiao Zhang, Tao Huang, Shunmin Zhu. 2021. Sailfish: Accelerating Cloud-Scale Multi-Tenant Multi-Service Gateways with Programmable Switches. In ACM SIGCOMM 2021 Conference (SIGCOMM ’21), August 23–28, 2021, Virtual Event, USA. ACM, New York, NY, USA, 13 pages. https://doi.org/10.1145/34522...
摘要
作为云通信的中心枢纽,云网关在公有云中是必不可少的。我们的研究表明,软件网关的水平扩展曾经可以持续多年,但面对当今云计算的大规模和快速增长,已不再具有未来持续提升的可行性。根本原因是CPU核的性能停滞不前,当流量增长远远超过摩尔定律时,CPU核很容易被重量级用户超载。为了解决这个问题,我们提出了Sailfish,这是一个云规模的多租户多服务网关,由可编程交换机加速。新的挑战是,由于多租户而导致的大型转发表不能装入有限的片上存储器。为此,我们设计了一种多管齐下的方法:
- 用于表共享的硬件/软件协同设计;
- 网关集群之间的水平表拆分;
- 单个节点进行流水线感知的表压缩。
与价格相近的x86网关相比,Sailfish减少了95%的延迟(2µs),在包长度小于256B的情况下提高了超过20倍的bps (3.2Tbps)和71x的pps (1.8Gpps)吞吐量。Sailfish已经在阿里巴巴云上部署了两年多。它是业内首个基于p4的云网关,单个集群承载数十Tbps流量,能够承载大型在线购物节的高峰流量。
1 介绍
公有云为客户提供了按需使用、可扩展的计算资源(例如,服务器、存储、网络)的能力,以实现基于云资源池和自动缩放的敏捷性、成本效率和业务连续性[36]。多年来,全球最终用户在公共云服务上的支出持续增长[12],而疫情的全球大流行加强了这一趋势[13]。为了满足日益增长的云的使用需求,亚马逊、微软、谷歌和阿里巴巴等公有云供应商投入了大量的前沿研发工作来解决性能、可扩展性、弹性、稳定性和全球分布式云基础设施的可靠性。
云网关是一种数据包转发设备,它在多租户环境中为全球分布的云资源提供高性能和可靠的连接[8,25]。为了满足客户的资源隔离要求,公有云供应商通过VxLAN [27]等Overlay网络协议在公有云内构建虚拟私有云(VPC) [41]。同一VPC内的虚拟机(VM)可以相互通信,而属于不同VPC的VM彼此隔离且透明。有时,一个VPC中的VM需要与同一区域或远程区域内不同VPC中的另一个VM通信。在其他情况下,一个VPC中的虚拟机想要访问公共Internet或企业本地数据中心(IDC)内的资源。云网关可以满足虚拟机之间、跨地域之间的通信需求,当需要跨VPC边界时,可以通过云网关构建隧道。
作为中央枢纽,网关在公共云基础设施中扮演着重要的角色,如处理东西流量(VM-VM),南北流量(VM-互联网)以及IDC/跨区域的连接整个云(VM-IDC/跨区域)。多年来,云计算经历了剧烈的流量增长。在数据中心内,服务器的以太网传输速率迅速增长到400GbE甚至更高[35]。2019年,阿里巴巴将整个电商业务上云[6],为其云网关贡献了数十Tbps的流量。因此,云网关在流量汇聚点的性能需要优雅地纵向扩展,以应对流量的爆发式增长,防止其成为系统的瓶颈。此外,云网关的稳定性对于24/7不间断的云服务交付也很重要。
除了转发性能外,云网关还需要承载大量的无状态和有状态转发表,用于各种云服务。具体来说,由于公有云中的多租户,包含VPC标识符和目的地址的转发表项很大,而考虑到公有云中VPC和VM的数量巨大,表项数量也很大[8]。在阿里云中,单个region可以承载数百万个VPC和数百万个VM。有时,即使在单个VPC中,顶级客户也可以购买数百万个VM。总的来说,云网关在转发逻辑、转发吞吐量、转发表大小、转发表种类等方面都与传统网络设备有所不同。
为了处理日益增长的工作负荷,水平缩放(即单个节点的,横向扩展)相乘的处理能力是在云中的通用智慧[15,16,18,31]。多年来,基于x86 的软件网关以前部署在阿里云的集群中,以应对云流量的快速增长。受益于内核bypass技术[9, 28]、硬件升级和持续的系统调整,这些x86机器多年来一直运行良好并且繁荣发展。然而,以阿里云今天的规模和增长率,这种横向扩展是不可持续的。原因有三方面。
- 首先,水平扩展增加了资本支出(即硬件采购成本)和运营支出(即整个集群的运营费用(例如工程师在系统故障排除中消耗的费用)以及管理和维护的复杂性,因为单个集群中需要数百个x86节点。
- 其次,由于单个CPU核的性能较弱,重量客户带来的流量突发导致CPU核很可能过载[ 37],进一步影响多租户的性能隔离,恶化服务级协议 (SLA)。CPU过载问题还迫使系统工程师为每个CPU内核预先分配更多的处理空间,从而降低网关集群利用率并进一步增加资本支出和运营支出。
- 最后,但并非最不重要的,近年来单个CPU内核的性能提升速度放缓[39]。众所周知,摩尔定律远远落后于互联网流量的增长[34]。但是,单个CPU内核的性能提升甚至比摩尔定律还要慢。也就是说,在可预见的未来,薄弱的单核CPU将持续受到越来越多的重磅流量挑战。
为了解决这个性能问题,我们提出了Sailfish,一种具有可编程交换ASIC的加速云规模多租户多服务网关。设计Sailfish具有挑战性,因为公共云中由于多租户导致的大型转发表不能完全适应可编程交换ASIC(例如Tofino)[7]的有限片上内存,ASIC中的内存空间并不像x86节点那样扁平[11]。为此,我们提出了一种多管齐下的方法。
- 首先,我们进行了表共享的软硬件协同设计,将少量更稳定的转发表放在硬件中,以覆盖频繁调用的云服务产生的大部分流量,而剩下的更不稳定的表或非常不稳定的表。大型有状态表放到软件。
- 其次,我们提出网关集群之间的水平表拆分,提高了可扩展性和故障隔离,降低了维护复杂度。
- 第三,对于单个节点,我们通过流水线折叠、流水线间表拆分、跨流水线表映射、内存资源池、TCAM保护和表项压缩等技术,在Tofino芯片上进一步进行流水线感知表压缩。单节点表压缩增加了单个集群中携带的条目数量,从而减少了集群数量以及硬件采购/维护成本。
两年多的Sailfish部署经验,包括集群构建、集群管理、灾难恢复以及我们学到的经验教训。我们的主要贡献总结如下。
- 我们提出了全球首个基于可编程交换机的多租户多业务云网关,并深入公开了技术细节和部署经验。
- 我们提出的解决方案包括对表共享进行硬件和软件协同设计,在网关集群之间水平分布表条目,并专注于单节点容量扩展,以解决当前使用的可编程ASIC的内存短缺问题。
- 在单个网关上,我们进行了表压缩,在IPv4场景中将SRAM占用率降低了38%,TCAM占用率降低了96%。在 IPv6 场景下,它降低了 85% 的 SRAM 占用率和 98%的TCAM占用率。
- 与大致相同的单位价格的x86网关节点相比,Sailfish降低了95%(2μs延迟),在包长<256B的小包情况下,提升了20倍bps(3.2Tbps)和71倍pps(1.8Gpps)的性能。与x86网关集群相比,Sailfish在一个区域内降低了90%以上的硬件采购总成本。Sailfish已经在阿里云上部署了两年多的迭代细化。业界首个基于P4的云网关,单个集群承载数十Tbps的电商流量,成功的支撑了大型网购节高峰时段的流量压力。
2 背景和动机
2.1 云网络网关
公有云网络。与私有云[29]只为少数选定用户运营不同,公有云[26]将其计算能力和存储能力打包成切片产品,出售给大量客户(即租客) 用于细粒度的资源共享以实现规模经济[21]。在这种多租户架构下,云服务购买者希望构建他们订阅的整个网络空间,并使用自定义的地址段、路由表和 ACL 规则进行配置,就好像他们在管理自己的本地网络一样。同时,公有云供应商也希望任何租户的(恶意)行为不会影响其他人使用的云资源,以保证与客户签署的SLA,即使物理基础设施是共享的。
为了满足上述要求,VPC[41]构建在公共云环境中,提供多个租户之间的逻辑资源隔离。为了创建多个相互透明的VPC,公有云网络不再只是网络节点之间进行数据传输的物理互连。目前主流公有云厂商依靠Overlay网络协议(如VxLAN [27])来实现网络复用和资源隔离,将基本的数据包转发任务留给了Underlay网络。具体来说,VxLAN是一个将虚拟化的第2层网络覆盖在第3层网络上的框架,它使用VxLAN网络标识符 (VNI) 来标识VxLAN段。只有在同一个VxLAN网段内(即共享同一个VNI)的VM才能相互直接通信。通过这种方式,一个VxLAN网段精确地实现了一个VPC进行隔离。
图1:云网关是各种云流量的中心枢纽。
网关在云中的作用。VPC的优势吸引了大量用户,他们从家中、办公室或地球上的任何其他地方与公有云中的VPC建立连接。图1展示了阿里云公有云基础设施的高层拓扑。如图1所示,阿里巴巴云有多个区域,每个区域包含大量的VPC。同一个VPC内的虚拟机共享同一个VNI以实现网络隔离。多个VM通过虚拟机管理程序托管在物理服务器上。在管理程序中运行的vSwitch允许VM之间的通信。在图1中,IDC是企业的本地数据中心,员工可以从这里连接到他们在云中的VPC。CEN是云区域和IDC之间的专线专线网络,提供高速IDC/跨区域通信。该云网关在公有云基础设施中起着至关重要的作用,因为它是整个云东西向流量(VM-VM)、南北向流量(VM-Internet)和IDC/跨区域流量(VM-IDC//Cross-region)的确切中心枢纽。我们在表1中详细阐述了这些流量路径和典型的云服务。以“IDC-VM”为例。来自IDC的流量将通过CEN、云网关、目的服务器上的vSwitch逐跳转发,直到最终到达目的VM。这条路线上的一个典型服务是租户从办公室登录到他的VM。
表1:跨云网关的不同流量路由上的典型云服务示例
云网关的数据包转发。在云流量汇聚点,云网关的职责是
- 根据目的VM地址区分到达流量,转发到包含目的VM的正确region/IDC/VPC;
- 根据目标虚拟机地址找到目标虚拟机所在的区域/IDC/VPC中的物理服务器。一旦托管目标VM的物理服务器确定,流量将被发送到此服务器,此服务器将进一步将流量传送到目标VM。
根据上述转发过程,云网关在其数据路径中至少包含两个重要的转发表:
- VxLAN路由表,
- VM-NC映射表(NC,节点控制器,在阿里云中托管虚拟机并控制虚拟机行为的物理服务器),如图2所示。
VxLAN路由表根据VxLAN封装报文的内部DIP找到正确的region/IDC/VPC范围。VM-NC 映射表根据VxLAN封装数据包的内部DIP以及从VxLAN路由表中获得的区域/IDC/VPC 范围,找到目标VM所在的确切物理服务器地址。在离开网关之前,数据包的外层DIP将被修改为从VM-NC映射表中获取的服务器地址,以便将数据包传送到目的VM。
图 2:云网关的数据包转发
在图2中,我们详细展示了“VM-VM(相同VPC,不同vSwitch)”和“VM-VM(不同VPC)”的转发过程。“VM-VM (相同VPC,不同vSwitch)“”是指两台虚拟机托管在不同的物理服务器上,但具有相同的VNI,而“VM-VM(不同VPC)”是指两台虚拟机在不同的物理服务器上,具有不同的VNI。
VM-VM(相同的 VPC,不同的 vSwitch)。到达的数据包首先使用VPC A(它的VNI)和 IP 地址 192.168.10.3(VXLAN 封装数据包的内部Dst IP,目标VM地址)查询VXLAN路由表,并命中VXLAN路由表的第一个条目,其中scope是“Local”,表示目的VM也在VPC A中,然后查询VM-NC映射表,命中第二项,显示目的VM的物理服务器IP是10.1.1.12。最后,数据包被转发,其外部Dst IP 修改为10.1.1.12。
VM-VM (不同的VPC)。最先到达的数据包VXLAN路由表的第二项;范围是“Peer”和“下一跳”是VPC B,这意味着目标VM不在原VPC,网关应该使用VPC B的VNI VXLAN进一步查找路由表,直到变成了“本地”范围。查询VPC B和192.168.30.5的VXLAN路由表时,到达第三项,范围为“Local”,即目的地址在VPC B内,然后查询VM-NC映射表,在第三项中找到自己的服务器IP,转发出去。
2.2 软件网关的演变
持久的架构可延长服务时间。如前所述,云网关位于流量汇聚点,因此,系统的稳定性对云服务的可靠性至关重要,任何网关故障都会对海量用户造成爆炸性影响。稳定性体现在两个方面:
- 数据包转发应该稳定且没有Bug(应该避免转发实例偶尔崩溃)
- 系统架构应该更持久服务时间(例如, 3-5 年)以节省生产环境中的开发费用,适应云规模和服务数量的快速增长(架构应具有可扩展性以处理不断增长的流量并允许迭代但易于处理的升级以容纳更多服务)。
图3:软件网关的演进
此外,开发应该是敏捷的,以确保新服务的快速部署,特别是考虑到这个网关是在阿里云的早期阶段开发的。综合以上要求,我们设计了XGW-x86,这是一个基于x86的软件网关,用于服务云流量转发(“XGW”意味着可扩展网关)。我们利用DPDK的内核旁路功能[9, 28] 来加速单节点性能(每个CPU核心1Mpps),并使用水平扩展[31]进一步扩展整个网关集群的数据包处理能力。由于其模块化软件设计,向XGW-x86 添加新服务很容易。该架构已经通过了五年多的生产环境部署的测试,主要演变如下图3所示。
服务集成到一个多功能网关中。为了快速部署新服务,我们在阿里云的早期阶段就构建了Ad hoc集群,即一个专用的XGW-x86集群用于一个特定的云服务。这样,新服务的开发、测试和在线部署不会影响其他已经部署的服务。随着流量的增加,一些集群快速扩张,而另一些集群利用率不足,这增加了系统资本支出。此外,异构集群需要不同的处理(即,我们需要指派专门的工程师到不同的集群进行开发和维护),而额外的集群间流量处理是不可避免的,这两者都提高了系统OpEx。为了降低CapEx和OpEx,当云服务变得更加稳定时,我们决定将异构的软件云网关合并为一个统一但多功能的网关,通过降低CapEx和OpEx延迟了架构的生命周期,但不损失可扩展性。服务集成后,单体系统也变得更加稳定,Bug更少,因为我们不再需要维护不同网关的独立、不同的代码库。
单个网关处理能力的垂直扩展。硬件速度逐年提高。因此,XGW-x86的服务时间有了全面升级,拥有更强大的CPU(更快的单核性能,更多的CPU核)和更高带宽的网卡。单节点容量的垂直扩展暂时减少了网关集群的规模以及硬件采购和维护成本。
2.3 软件网关的局限
非常稳定的XGW-x86架构虽然在过去几年经受住了流量处理负载和云服务的变化,但随着阿里云流量的持续增长,随着时间的推移也积累了很多问题。当然,其他云供应商可能仍然使用基于软件的解决方案来很好地管理这些问题[16, 31]。在这里,我们尝试根据自己在阿里云的经验提供观察和见解。
网关集群的高CapEx和OpEx。软件网关集群以处理云区域中的流量。假设流量为15Tbps [20, 30],每个网关最大可以处理100Gbps。然后,需要15Tbps / 100Gbps = 150个网关。在生产环境中,我们需要为服务的稳定性预留足够的处理空间。如果网关设计为50Gbps(即50%水位)转发,网关数量将增加一倍。此外,考虑到容灾的1:1备份,数量将进一步翻倍至600!软件网关的单位成本并不便宜,因为每个网关包含2/4个高端至强处理器[5]和40/100GbE网卡。假设每个网关的成本为O($10K),单个区域的总成本将达到O($10M)。由于两个原因,软件网关也会带来相当大的维护开销:(1) 在“横向扩展”模式下,每个网关共享相同的转发表,并且控制器需要同时更新所有网关,这容易出现延迟和一致性问题(它将所有表安装到一个XGW-x86网关需要十多分钟,即使在控制器启用了某种程度的多线程,更新数百个网关也很耗时),以及(2)网关的数量增多也增加了故障排除的难度,因为更多的网关引入了更多的潜在故障源。
超出负载均衡器的最大下一跳限制。云网关放置在负载平衡交换机/路由器后面,该交换机/路由器进行基于ECMP流的转发[23],以将流量平均分配给这些网关。然而,商业负载均衡器通常仅限于允许少于64个可能的下一跳(例如,在瞻博网络安全设备上,ECMP集中的下一跳地址的最大数量为16 [3]),这限制网关集群的大小。为此,云区域中的数百个网关节点必须在不同的负载均衡器后面划分为多个较小的集群,这进一步增加了维护的复杂性。
图4 XGW-x86网关的CPU过载(展示的是32个CPU核中的前5个核)
图5:使用XGW-x86的区域在一周内的流量率和丢包率
图 6:XGW-x86一周内同一地区的CPU消耗。
由于流量突发导致CPU过载。虽然我们在实际部署中已经预留了足够的安全余量,但我们仍然观察到由于流量爆发导致CPU核心的高利用率,特别是在“双11”这样的大型网购节期间。在图4中,我们观察到网关的CPU核1在几天内持续过度使用,而其他CPU核的负载都很轻(为清楚起见,我们只显示了按利用率排序的前5个核,共32个)。CPU核过载会不时造成某个区域的丢包,如图5所示(注意图4所示的CPU核利用率是粗粒度采样的,CPU核利用率达到100%时,会出现丢包,即使很短的时间)。在最坏的时候,整个区域的丢包率达到10-5 - 10−4 (在第6天)。在多租户云中,如果租户的流量在该内核上,CPU核过载会降低租户的SLA。CPU内核过载有两种可能:(1) 网关之间的负载不平衡,以及 (2) CPU 内核之间的负载不平衡。从图6中,我们发现在同一时间段内,网关之间的处理负载是完美平衡的。也就是说,负载在CPU内核之间分布不均。
图7:重击流导致的 CPU 过载
水平扩展很常见,网关之间的均衡很容易,CPU核之间的均衡则不然。我们探讨了核间负载不平衡的根本原因。图7显示了在历史CPU过载场景中过度使用的CPU内核上的top-N 流量的流量比例。我们发现在大多数情况下,Top-1 和 Top-2 流主导着流量。也就是说,流量不平衡和少量重击者会导致CPU核之间的负载不平衡。XGW-x86遵循run-to-completion模型,进行基于流的哈希,并通过RSS (Receiver side scaling)技术[22]将从网卡接收到的数据包分发到多个RX队列,在CPU核之间对数据包进行负载平衡。基于流的散列保证了流内有序的数据包处理;然而,如果多个重击流被哈希到同一个CPU内核中,它也会导致潜在的CPU内核过载,即使哈希算法本身是完全随机的。有时,阿里巴巴云中的一条流量甚至可以达到几十Gbps, CPU过载问题直接影响到向重要客户销售带宽。将run-to-completion 模型更改为流水线模型可能会改善问题,但x86 CPU上的流水线模型也有其自身的问题,例如L3缓存中的核间传输性能损失[46]。事实上,一些网络处理器确实有能力将同一流的数据包哈希到多个数据包处理引擎以实现基于数据包的负载平衡,并依靠专用的序列保留硬件进行快速数据包重新排序[42]。然而,基于通用处理器和DPDK的XGW-x86的实现由于缺乏专用硬件而无法实现高性能的数据包重新排序。实际上,网关/CPU核之间的负载平衡就像将球随机扔进垃圾箱[ 33]。箱子越小,溢出的可能性就越大。尽管水平扩展是云中的普遍智慧,但它并不总是运作良好。
图 8:2010-2020年的CPU性能(单核和多核)和ToR交换机端口速度
单核CPU性能停滞。我们已经描述了软件网关限制的根本原因,但一个自然要问的问题是:能否通过未来的技术创新顺利解决?我们用历史来预测未来,但结果是悲观的。图8为2010-2020年Intel i7 CPU性能(单核和多核)和ToR交换机端口速度,前者大致反映了软件网关的处理能力,后者部分反映了面临的流量负载通过云网关。2010年到2020年,端口速度从10GbE增长到400GbE(40倍),多核性能提升4倍;然而,单核性能提升仅为2.5倍。互联网流量增长远超摩尔定律[34],而摩尔定律也超越了单个CPU内核的性能提升。基于这些结果,XGW-x86将持续受到越来越多重量级选手的挑战。
3 硬件网关和挑战
3.1 硬件可选项
XGW-x86暴露的问题促使我们寻找更强大的解决方案来保护云网关免受流量泛滥的影响。2017年末,我们自然而然地转向硬件,并从速度、成本、可编程性和功耗方面对以下三个候选方案进行了彻底调查。
固定功能的ASIC。博通Tomahawk 2/3 [1等固定功能ASIC可提供超过10Tbps的交换吞吐量,同时具有受限的功耗和可承受的成本。由于缺乏完整的可编程性,这些芯片最初是为高速交换机制造的,然而,它们并不是我们多功能云网关的最佳选择。首先,阿里云部署了许多需要ASIC供应商额外支持的专有协议(例如Vtrace [17])。其次,固定功能的ASIC不能很好地适应云服务的持续变化。ASIC的上市时间对于服务驱动的云网络来说太长了。
FPGA。FPGA是完全可编程的,但具有陡峭的学习曲线。由于频率相对较低,FPGA的交换性能一般低于400Gbps,这使得它们更适合在终端主机上构建智能网卡[19],而不是在中央HUB的云网关。最近,一些提议试图将FPGA的处理灵活性推入网络核心[32]。此外,FPGA 比固定功能的ASIC更昂贵,并且在同等性能下更耗电。
可编程ASIC。可编程交换ASIC兼具固定功能ASIC和FPGA的优点,允许程序员灵活定制转发逻辑,快速适应云服务变化,同时保持高性能和低功耗[10, 11]。此外,可编程交换ASIC价格合理。据了解,基于Tofino的交换机单价与XGW-x86大致相同。也就是说,我们可以用一个基于Tofino的交换机替换许多XGW-x86网关,这样可以提供相同的转发性能,但成本大大降低。在2017年末,我们并没有太多实现云网关的可编程ASIC的选择,所以我们当时选择了Tofino。但是在2021年,许多芯片供应商都宣布了他们的可编程交换ASIC(例如Broadcom的Trident 4[4]、Cisco的Silicon One[2]),我们相信我们的高级设计范例和Tofino 的经验可以扩展到其他芯片。
3.2 可编程交换ASIC
图 9:Tofino 的数据包转发架构
图9显示了Tofino基于流水线的转发架构。Tofino有四个独立/隔离的流水线用于数据包处理。在每个流水线上,到达的数据包将依次通过Ingress Pipe的Parser/Match-Action Unit/Deparser和Egress Pipe的解析器。每个流水线都有SRAM和TCAM内存资源,它们平均分配到该流水线的多个阶段。具体来说,每个stage都有自己的SRAM和TCAM,即使在同一个流水线中也不能访问其他阶段的内存资源(其他流水线中的内存也是不可访问的)。片上存储器非常有限 (O(10MB))[24],并且TCAM的数量远小于SRAM的数量。每个阶段查表的中间结果保存在元数据中,在整个Ingress或Egress Pipe内共享,但不能直接在它们之间传输。
3.3 技术挑战
更长的表条目具有更大的表条目号。VxLAN路由表和VM-NC映射表覆盖了大部分云流量。在公有云中,租户/VPC的增长,以及它们之间的互联,都有助于VxLAN路由表的扩展。租户分配的虚拟机数量的增长有助于扩大VM-NC映射表(一些顶级客户甚至可以在单个VPC中购买数百万个虚拟机)。根据我们的统计,阿里云的一个大云域可以有O(1M)个VPC和O(1M)个VM,导致VxLAN表和VM-NC表非常大。除了表项编号外,与L2/L3设备相比,VxLAN表和VM-NC表都有更长的表项。因为除了存储目的IP地址,VXLAN表和VM-NC表还需要存储24位的VNI字段。
表2 Tofino的
有限的总片上存储器容量。由于大容量的外部DRAM,存储O(1M) VXLAN路由表和O(1M) VM-NC映射表对于XGW-x86来说很容易;然而,对于上面提到的具有较小O(10MB) 片上存储器的Tofino芯片来说,同样是困难的。除了内存资源有限外,流片时SRAM/TCAM的比例也是固定的,无法适应不断变化的云服务要求。此外,由于价格昂贵,TCAM明显更加稀缺。然而,与云网关流量的精确匹配相比,LPM查找需求的百分比并不小。表2显示,如果我们直接将这两个主要表放入Tofino芯片中,这些表所需的内存将远远超过可用的内存。
处理各种云服务。除了VxLAN路由表和VM-NC映射表,网关还需要携带其他的表,用于各种云服务。一些表是有状态的并且表条目超大,例如具有O(100M)条目的SNAT。一些表是易变的,例如为按需流量负载平衡分配的临时表,该表仅在在线购物节期间激活。有些表是与QoS相关的,根据与客户签署的SLA安装,例如Meter、Counter、ACL表。鉴于片上内存有限,如何在Tofino中安排这些异构表需要仔细考虑。
处理逐年增长的IPv6流量。除了处理IPv4流量外,由于越来越多的客户将业务转移到IPv6[14],云网关的内存设计面临更多挑战。首先,IPv6有更长的表条目,这使得整体内存消耗更高。其次,随着IPv6需求的不断增长,我们需要考虑动态分配片上存储器以满足IPv6表项不断增长的需要。动态内存分配容易产生内存碎片,导致原本不足的片上内存利用率低。因此,如何按需分配内存以有效满足IPv4和IPv6成为另一项重大挑战。
非连续内存空间上的表放置。Tofino有多条流水线,每条流水线有多个阶段。每个阶段都有自己的本地内存资源,不能被其他阶段访问。换句话说,可编程ASIC上的内存空间不是平坦和连续的,这与x86架构完全不同,在x86架构中,虚拟内存机制保证了完全连续的地址空间。幸运的是,Tofino的编译器可以通过表拆分和映射到多个阶段来自动处理同一流水线内跨阶段的大型表。但是,编译器不会解决跨流水线的表放置问题。此外,如前所述,在Tofino架构中不允许在入口流水线和出口流水线之间传输元数据作为对程序员的另一个架构约束。总之,我们应该完全了解映射逻辑表的体系结构约束以及它们与物理内存布局的关系。
4 设计与实现
4.1 设计综述
图10 Sailfish的架构
为了成功处理云规模(高吞吐量)、多租户(巨大的VXLAN路由表和VM-NC映射表)和多服务(不同的转发表)流量,我们设计了Sailfish,一个硬件/软件集成的云网关系统。整体架构和高级设计如图10所示。我们利用多管齐下的方法从三个角度解决片上存储器不足的问题。
软硬件协同设计。Sailfish由基于Tofino的硬件网关(XGW-H)和基于x86的软件网关(XGW-x86)组成。XGW-H速度超快,但内存有限且内存布局受限,而XGW-x86内存空间巨大,具有完全可编程性但性能有限。通过分析不同云服务的流量特征,我们将XGW-H放在一个区域内的XGW-x86之前。然后我们利用XGW-H来存储一些经常被大部分流量命中的关键表,并使用XGW-x86作为补充来保存剩余的被小部分流量击中的易变表和无法压缩放到XGW-H中的巨大状态表。(图10中的a)。
XGW-H集群之间的表拆分。Sailfish在一个区域内的XGW-H集群之间进行水平表拆分,以进一步减少每个XGW-H中存储的表条目数量。这里,“水平拆分”是指每个XGW-H存储所有转发表,但只存储每个表中的一部分条目。多个XGW-H集群覆盖了一个区域内的所有条目,而一个集群只负责部分租户的条目。在一个集群内,多个XGW-H设备维护相同的表条目,相互分担流量负载和备份。(图10中的b)。
单节点表压缩。Sailfish对每个XGW-H进行表压缩,以便将更多的表条目贪婪地放入单个节点中。这些优化包括流水线折叠、流水线之间的表拆分、跨流水线的表映射、内存资源池、TCAM保护和表条目压缩。单节点表压缩增加了一个集群中承载的条目数量,从而减少了必要的集群数量、资本支出和运营支出。(图10中的c)。
4.2 软硬件协同设计
由于云流量快速增长,XGW-x86很难承载所有流量。可编程交换ASIC的出现使硬件网关能够以高性能处理各种云服务。然而,对于硬件网关来说,片上存储器太有限,无法存储所有的表条目。因此,软硬件结合是云网关演进的一个可行方向。通过对真实云流量的数据挖掘,我们发现流量完全遵循“二八原则”。例如,在典型的云区域中,5%的表项承载了95%的流量,而其余95%的表项仅承载了5%的流量。基于这一观察,我们制定了硬件和软件合作的原则。
- XGW-H是放置在XGW-x86前面的默认网关,用于吸收大部分流量。
- XGW-H存储了几个被大部分流量频繁命中的关键表,保证了基础云服务的可靠性和稳定性。此外,XGW-H负责将剩余流量引导至XGW-x86。
- XGW-x86维护着大量易变表,受到一小部分流量的影响。它还存储无法轻易压缩到 XGW-H中的大型有状态表。XGW-x86中连续内存空间的完全可编程性简化了长尾服务的频繁表更新。
- 一般情况下,不稳定、流量较少的新生业务由XGW-x86承载,而流量大且稳定的成熟业务上交给XGW-H。这样,概率较高的不稳定业务的故障不会影响XGW-H的流量转发。所有表共享决策都由中央控制器预先确定。
- 考虑到性能上的巨大差异,在将流量转发到XGW-x86之前,需要在XGW-H进行速率限制,以进行过载保护。
图 11:用于有状态SNAT流量处理的XGW-H和XGW-x86协作
图11显示了XGW-H和XGW-x86之间合作进行有状态SNAT流量处理的示例。一些客户拥有大量虚拟机,但只有少数公共IP。为了让所有的虚拟机都能访问公网,云网关需要SNAT。SNAT将5元组映射到公网IP和端口。因此,SNAT表中的条目数由会话数决定,该数远大于VM 数。SNAT表的条目数可以达到O(100M),而VM-NC表的条目数只有O(1M)。SNAT表太大,XGW-H装不下,每个表项的使用频率也不是很高。此外,会话和公共IP/Src端口之间的映射是不稳定的。所以我们把SNAT表放在XGW-x86中。
如红色箭头所示,VM通过SNAT访问公网。请求数据包首先到达XGW-H。XGW-H根据报文中携带的特殊VNI标签判断报文要访问公网,需要SNAT。然后,它将数据包转发到XGW-x86。XGW-x86根据其5元组找到对应的公网IP和端口,然后替换其内部Src IP和内部Src端口,去除VXLAN隧道并转发数据包。蓝色箭头是来自公网的响应。公网根据请求包的Src IP向VM发送响应包,因此响应包会直接到达XGW-x86,然后XGW-x86添加VXLAN隧道发送给VM。
XGW-x86和XGW-H共享表后,对于一个典型的几十Tbps流量的云区域,同时考虑安全裕度和容灾,我们大幅减少了硬件的成本,用于主要流量处理的数百个XGW-x86变成了10个XGW-H和用于回退流量处理的四个XGW-x86。
4.3 XGW-H集群间的表拆分
图12:XGW-H集群之间的表拆分
如图12所示,在一个区域中,我们根据 VNI(即租户ID)将表条目水平拆分为不同的XGW-H集群。每个集群维护所有表和每个表中的一部分条目。表分区和条目分布由中央控制器管理。在数据平面,流量根据VNI通过XGW-H集群前面的负载均衡器进行分配。与垂直表拆分或基于流的哈希相比,水平表拆分有四个主要优点。
- 良好的可扩展性。由于XGW-H的片上内存有限,直接维护每个集群中的所有表条目显然是不可扩展的。但是如果我们进行垂直表拆分,即将所有条目的不同表拆分成不同的簇呢?实际上,水平拆分的好处是,当新的租户加入到云中时,我们只需要在一个集群中插入新的表条目,或者如果原来的集群内存不足,则分配一个新的集群。但是垂直表拆分无法实现这一点。
- 错误隔离。在实际部署中,对于这样一个复杂的系统来说,由于仓促开发或配置错误导致的软硬件错误在所难免。水平拆分可以有效约束一个簇内一些错误条目的影响范围,因此,一个集群的故障不会影响同一地区的其他集群。否则,影响范围将扩展到整个区域,即使大多数集群与那些错误条目无关。
- 易于处理的流量负载平衡。事实上,为了负载均衡,我们还可以使用基于流的哈希将流量分配到多个集群。但是,通过哈希进行负载平衡有点不可控。相比之下,水平拆分只需添加或删除相应的条目,即可精确管理特定集群上的流量负载。
- 降低维护复杂性。水平表拆分维护相同的表,减少集群中表项的数量,从而降低表管理的复杂性和灾难恢复时间。
4.4 单节点表压缩
簇间表拆分后,每个簇只需要携带部分表项。但这并不意味着我们可以无限分裂并使用无限数量的集群来保存条目。有两个原因:
- 表拆分有限制,因为VPC是最小拆分粒度,但是,一些VPC(例如顶级客户)包含数百万个条目,挑战单个集群的容量;
- 我们需要考虑资本支出和运营支出来构建集群。
因此,我们进一步进行单节点优化,以扩大 XGW-H 的容量以容纳更多条目。
图13:用于存储更多表条目的流水线折叠
流水线折叠。如果四个流水线包含相同的转发表并且并行工作,XGW-H可以达到6.4Tbps的转发吞吐量。通过在集群中添加更多网关,可以进一步提高吞吐量。也就是说,对于XGW-H来说,吞吐量足够,而内存不足。因此,我们建议“流水线折叠”作为一种折衷,以牺牲吞吐量来获得双倍的内存容量以存储更多的表条目。如图13所示,我们使用 Ingress Pipe 0/2 作为数据包入口点。然后,数据包进入Egress Pipe 1/3,但这些流水线的端口设置为 Loopback模式,因此数据包在离开Egress Pipe 1/3后将通过相同的端口进入Ingress Pipe 1/3。最后,数据包将通过出口Pipe 0/2发出(入口Pipe 1 进入出口Pipe 0,入口Pipe 3 进入出口Pipe 2)。这种设计除了将转发吞吐量减半外,该设计还将转发延迟加倍。然而,添加O(1 μ S)到所述端至端延迟最终用户是察觉不到的。并且,用于容纳更多表条目的双倍内存容量确实是一个巨大的收益。考虑到Tofino的架构约束,我们总结了在四个流水线中分配表的原则如下。
- 表应放置在入口Pipe 0/2、出口Pipe 1/3、入口Pipe 1/3 和出口Pipe 0/2 中,遵循表查找顺序以匹配流水线折叠中的数据包流。
- 元数据不能在Ingress Pipe和Egress Pipe之间直接传输。如果确实需要跨不同流水线传输元数据,我们必须将元数据附加到数据包中,这称为桥接。桥接会增加数据包长度从而影响转发吞吐量。通过流水线折叠,可能的桥接数量从1增加到3。因此,对于需要共享相同元数据的表,我们建议将它们放在同一个流水线中,以尽量减少可能的桥接数量以及吞吐量损失。
- 表应该均匀分布在不同的流水线中,确保每个流水线将来都有足够的空间进行表扩展,使系统可以扩展,而不需要频繁地重新映射现有的表。
图14:流水线之间的流量拆分
流水线之间的表拆分。当数据包离开入口Pipe 0/2 时,它们将进入出口Pipe 1/3。最初,出口Pipe 1 和出口Pipe 3 包含相同的表条目。为了减少表冗余,我们可以在出口Pipe 1中存储一些条目,在出口Pipe 3中存储其他条目,使用一些哈希函数将流量划分到不同的流水线中(图14)。此处描述的水平表拆分设计与第4.3节中的非常相似。不同之处在于我们在Tofino芯片上的流水线之间拆分表,而不是在一个区域中的集群之间拆分表。一般原则是尽可能平均地分割条目以确保每个流水线承载的流量是平衡的。例如,我们可以根据VNI或内部Dst IP的奇偶校验来拆分条目。
图15:跨流水线映射大表
跨流水线映射大表。流水线折叠后,流水线0和流水线2中的表相同,流水线1和流水线3中的表相同。Pipeline 0/2 和 Pipeline 1/3 中的表一起提供了完整的转发逻辑。由于每个流水线的内存都是隔离的,所以流水线0/2和流水线1/3之间可能存在不平衡的内存占用。如图15所示,查表顺序为A-B-C-D。我们将表A放置在入口Pipe 0/2中,将表B放置在出口Pipe 1/3中,将表C放置在入口Pipe 1/3中。此时,流水线1/3中还有一些空闲空间,但不足以容纳整个表D。而Pipeline 0/2中还有很大的空闲空间。我们将表D的一部分放在Ingress Pipe 1/3中以充分利用Pipeline 1/3,而我们将其余部分放在Egress Pipe 0/2中,消耗Pipeline 0/2的剩余内存来存储表D的其余部分. 通过跨流水线映射大表,我们打破了不同流水线之间的资源隔离,让表放置更加自由。
IPv4/IPv6表池。可以将专用的IPv6表与IPv4表一起分配,以允许它们彼此独立更新。这样,一张表的扩展不会影响另一张表提供的服务。但是,由于IPv4/IPv6的流量比例在不断变化,单独的表可能会因为内存占用效率低而导致内存浪费或内存不足。我们的策略是汇集IPv4和IPv6内存资源。对于任何以IP为key的表,同时支持IPv4和IPv6,保证IPv4/IPv6的比例可以任意调整。具体来说,可以将IPv4密钥扩展为128位以与同表中的IPv6密钥对齐;或者IPv6密钥可以压缩为32位以与IPv4密钥对齐。对于VXLAN路由表,我们选择第一种策略以方便进行LPM搜索;对于VM-NC映射表,我们选择第二种策略,因为它只需要精确匹配。表池策略也可以应用于其他云服务。
图16:使用ALPM的转发表分区
大FIB的TCAM守恒。容纳整个VXLAN路由表与TCAM可以保证搜索效率。但是Tofino上的TCAM资源非常有限。此外,TCAM/SRAM的内存比对于芯片来说是一个常数,但LPM的查表要求或精确匹配会随着时间的推移而变化。为了解决这个问题,我们实现了算法LPM(ALPM)[40],以稍微降低查找效率和更多的SRAM使用为代价,灵活地减少TCAM的使用。如图16所示,整个路由表分为两级,第一级存储在TCAM中,索引存储在SRAM中的第二级。TCAM占用率和查表效率之间的权衡可以通过调整第一级的深度来实现。
压缩较长的表条目。如果表项的键太长,我们尝试将其压缩为较短的哈希摘要以节省内存空间。例如,在使用IP双栈构建VM-NC表时,我们进行IPv4/IPv6表池化,并将IPv6密钥压缩为32位进行对齐。IPv4/IPv6表池从128位压缩到32位会导致两种冲突。第一个是压缩的IPv6和原始IPv4之间,可以通过在表条目中使用附加标签轻松区分。第二个是在两个压缩的IPv6密钥之间,它可以通过一个额外的小表来解决,以保存包含完整128位密钥的冲突条目。在VM-NC表中进行IPv6查找时,我们将首先使用128位密钥查找冲突表,如果冲突表中没有项目,则使用32位压缩密钥的IPv4/IPv6表。根据我们的经验,128到32的哈希压缩会产生非常有限的冲突,因此专用于解决冲突的表不会消耗太多内存。
表 3:优化后的内存占用
优化后的内存使用情况。经过以上优化,VXLAN路由表和VM-NC映射表两大表终于可以适配到Tofino芯片中(如表3所示)。由于我们进行了IPv4/IPv6表池化,内存占用不会随着IPv4/IPv6的流量比例而进一步变化。与表2的逐案结果相比,在100% IPv4场景下,SRAM的使用量减少了38%,TCAM的使用量减少了96%;在75% IPv4和25% IPv6场景下,SRAM的使用量减少65%,TCAM的使用量减少97%;在100% IPv6场景下,SRAM使用率降低85%,TCAM使用率降低98%。
5 评估
5.1 XGW-H性能
XGW-H是在Tofino 6.4T上开发的,上千行P4-16代码。我们在分步内存优化、整体内存消耗以及转发性能方面评估XGW-H的单节点性能,并与XGW-x86进行比较。然后,我们在实际部署中评估Sailfish的性能,重点关注大型云区域的长期丢包、流水线之间的流量负载分布、硬件和软件之间的流量共享以及表更新频率。
图17:逐步压缩后的内存使用情况
逐步表压缩。图17为VXLAN路由表和VM-NC映射表分步压缩后的内存占用情况。在任何优化之前,SRAM和TCAM占用率分别达到102%和389%(召回表2)。流水线折叠后,以牺牲吞吐量为代价,SRAM和TCAM的内存占用减少了一半。在流水线之间进行表拆分后,每个流水线中的内存占用进一步减少了一半。在IPv4/IPv6表池中,我们将IPv4密钥扩展到128位以进行对齐以进行LPM查找,因此,TCAM占用率会增加。同时,我们还将IPv6密钥压缩为32位,以便在VM-NC映射表中进行精确匹配。结果是减少了SRAM占用。最后,在进行ALPM进行TCAM保护后,TCAM占用率大大降低到11%,而SRAM占用率翻了一番,达到36%。
表 4:总体内存资源消耗。
整体内存消耗。表4显示了XGW-H考虑所有实际表的整体内存资源消耗。流水线0/2和流水线1/3占据SRAM的69%和TCAM的32%。我们的设计有效地解决了可编程ASIC芯片中存储数百万个表条目的内存短缺问题,并且仍有增加未来表条目的空间。
图18:XGW-H的转发性能
转发性能。图18为XGW-H与XGW-x86的转发性能对比,有吞吐量、数据包速率和延迟。在大致相同的单价下,XGW-H的吞吐量是XGW-x86的20倍以上(图18(a))。当端口带宽满时,我们对XGW-H和XGW-x86的包转发速率进行压测。如图18(b)所示,XGW-H的包速率是XGW-x86的72倍。即使对于非常复杂的云服务逻辑,XGW-H在小于256B的数据包时仍然可以达到线速,而XGW-x86在大于512B的数据包时达到线速。我们在没有后台流量的情况下测试了XGH-H和XGW-x86的转发延迟。如图18(c)所示,虽然XGW-H使用流水线折叠方式让数据包通过多一条流水线,但平均时延仍然只有2µs,比XGW-x86低95%。对于XGW-H,等待时间变化从2.173μs至2.303μs代表128B-1024B IPv4通信和从2.177 μs至2.306 μs代表128B-1024B IPv6通信。
5.2 Sailfish的性能
图19:Sailfish在为期一周的网购节期间在三大云区域的表现
丢包率。图19展示了大型网购节期间,Sailfish在三个大云区的表现。三个区域的峰值流量都是几十Tbps。它表明Sailfish在生产环境中提供了非常稳定的性能,仅具有从10−11到10−10的较小丢包率,比XGW-x86低六个数量级(回想一下图5)。超低的丢包率主要得益于Tofino的大容量流水线提供的大安全裕度。
图 20:流水线之间的平衡流量分布
(集群视图)
图21:流水线之间的平衡流量分布
(时间视图)。
流水线之间的流量负载分布。我们在流水线之间水平分割流量,以将每个流水线中的表条目减少一半。拆分方法可以是哈希或利用历史数据挖掘的服务特征。如图20和图21所示,流量可以在集群和时间维度的管道之间以良好的平衡进行划分。与重击流导致的CPU过载不同,它几乎不会导致流水线之间的极端不均匀,因为流水线数量很少,每个流水线都有巨大的处理能力。
图22:少数流量到达包含大部分转发表的 XGW-x86
图23:VXLAN路由表的定期更新和突发更新。
XGW-H和XGW-x86之间的流量共享。图22说明了XGW-x86在执行表共享策略后在Sailfish中承载的流量的数量和比例。它表明,在生产环境中,XGW-x86只需要处理非常小比例的云流量( < 0.2 ‰)。即大部分流量到达少数表,由XGW-H以超低延迟处理。剩下的几Gbps流量可以由XGW-x86安全处理,而不会导致任何CPU核过载问题。
表更新频率。图23显示了一个月内不同集群的VXLAN路由表中条目编号的变化。大多数情况下,表格更新非常缓慢,表格条目的突然增加很少发生。由于定期表更新发生的频率相对较低,因此可以轻松处理它们。突然增加的主要原因是顶级客户的到来,他们购买了大量的虚拟机或一次性进行了一批路由更新。尽管突然的变化可能会影响我们系统的稳定性(例如,导致集群突然扩大),我们会得到顶级客户的通知,并在实际部署中提前知晓。只要我们能够在顶级客户的流量到来之前准备好所有更新的表条目,我们仍然可以毫无风险地处理这种特殊情况。
6 经验
6.1 部署经验
集群建设。在生产部署中,分配的云网关数量取决于客户的服务需求。在将网关上线之前,首先将所有表条目从中央控制器下载到所有网关。由于表项和网关数量较多,在填表过程中可能会由于软硬件错误、配置错误或网关内存不足而导致控制器和网关之间的表项不一致[43]。因此,需要定期进行一致性检查。然后,我们将部署探针生成器来生成涵盖尽可能多的测试场景的各种探针数据包。最后,我们将修改上游设备中的路由,以允许用户流量进入网关集群。如果用户流量过大,我们会逐步接纳流量。
集群管理。在网关集群运行期间,我们定期监控表水位、流量率和丢包率。我们必须在两种情况下部署新集群:(1)表大小超过可用内存,以及(2)流量超过可用处理能力。一般来说,表项增长很容易预测,大部分时间是线性增长,而顶级客户会提前通知突然增长。相比之下,流量增长很难预测。如果平均流量过高,我们必须依靠XGW-H提供的安全余量来适应流量突发并部署新集群。在实践中,我们会为XGW-H和XGW-x86中的表预留安全水位,以允许租户添加新条目。当水位接近安全阈值时,我们将暂时关闭集群资源的出售,并考虑将新用户放到另一个集群或构建一个新的集群。为了保证稳定的转发性能,每个端口也会预留一个安全水位来监控流量速率和丢包率。如果丢包率接近安全阈值,将提醒控制器采取进一步措施。在流量大的网购节,我们会刻意提高安全水位,通过减少发送到控制器的告警数量,进一步提高网关的允许吞吐量。其他系统指标(例如CPU、内存和磁盘利用率)也将受到监控。
灾难恢复。容灾设计在集群、节点和端口等不同层次上。在集群层面,所有网关集群都严格遵循1:1备份。备份集群为热备,配置与主集群相同。实时监控主集群的健康状态,任何异常都会提醒控制器修改上游设备中的路由,以便流量重新路由到备份集群。在节点层面,当某个网关报告硬件故障或接近其安全水位时,该网关将下线,同一集群中的其他网关将分担该网关的流量负载。如果同一个集群的网关都忙,我们会求助于全局预留的冷备网关。在端口层面,当端口出现异常抖动或持续丢包时,该端口将被隔离,并通过修改上游设备的路由将流量迁移到其他端口。
6.2 经验教训
Sailfish准备好在阿里巴巴之外提供服务了吗?我们在Sailfish的概念和实现上投入了大量人力,以将云级转发表融入Tofino有限的片上存储器中。在阿里云,我们在流量暴增的推动下,不得不转向硬件。迄今为止,Sailfish的表现并没有让我们失望,因此值得。但从中小云厂商的角度来看,短期内XGW-x86或许足以解决他们的问题。即使使用可编程开关,也可能不会面临内存资源不足的问题。但从长远来看,随着云业务快速增长而CPU性能提升放缓,我们认为他们迟早会面临这些问题。因此,我们认为Sailfish并非微不足道。
Sailfish的长期生存能力如何?Sailfish的长期生存能力主要受每Gbps消耗的SRAM/TCAM或多或少趋势的影响。通常,内存消耗(即,表大小)由虚拟机数量决定,而流量速率由租户的服务需求决定。一种极端情况是虚拟机数量迅速增加而流量增长停滞。在这种情况下,Sailfish将不断受到表条目快速增长下内存不足问题的挑战。然而,根据我们的观察,阿里云这些年来每个VM的流量率一直在持续增长,这也意味着每Gbps消耗的SRAM/TCAM一直在下降。如果这种趋势在未来不会逆转,Sailfish应该具有长期生存能力。
开发难度有多大?P4是一种特定领域的语言[10]。与C语言开发的XGW-x86相比,XGW-H的开发过程更简单一些,新业务的敏捷部署也有保障。但是,开发人员仍然需要了解Tofino 的流水线模型和内存约束,使得可以进一步优化。此外,作为最近的一项创新,可编程交换ASIC的工具链不足,例如用于代码覆盖的测试工具。我们需要编写大量测试用例并手动检查结果以验证我们功能的完整性。我们相信一个完整的工具链可以提升可编程ASIC的开发效率。
管理异构集群有多难?Sailfish是一个包含XGW-H和XGW-x86的异构网关系统。通常,与同构系统相比,异构系统更复杂且更难管理。复杂性体现在不同的节点形式以及异构节点之间的一致性和协调性。在Sailfish中,我们尝试通过在异构节点上构建统一的抽象层来管理复杂性。这样,网络运营商或控制器就不会意识到XGW-H和XGW-x86之间的低级差异。过去管理同构XGW-x86的经验可以继承。
为生产环境构建稳定的网关。对于位于整个云中心枢纽的云网关,稳定性和性能同等重要。云网关故障将影响大量用户及其服务。例如,在我们的设计中,转发表在具有预下载配置的软件和硬件网关之间共享,以保证确定性的查找性能。但是,在其他系统中,如TEA[24],系统中涉及软件和硬件之间的缓存替换,以将频繁使用的条目适合硬件开关。目前,我们不喜欢基于缓存的设计,以避免在某些极端情况下缓存崩溃和性能突然下降。我们遵循“奥卡姆剃刀原则”来保护我们系统的简单性和可靠性。
复杂云服务的元数据调整。云服务很复杂,我们需要使用大量元数据来存储流水线表查找过程中的中间结果。但是,我们注意到存储元数据的片上PHV(数据包头向量)资源也很稀缺,尽管它们尚未耗尽。因此,如何优化查表逻辑以及元数据组织以减少PHV的消耗也是一个值得探索的有趣话题。
7 相关工作
之前的一些工作已经研究了多租户云以及云网关的设计和实现[8, 25, 38, 45]。作为多租户云的开创性工作,[ 25]通过软件实现了一个云网关,承载了数千条隧道,这对于小型云厂商来说可能足够了,但对于大型云厂商来说可能不适用。普罗泰戈[38]提出了一种云规模的多租户网关,具有软件节点集群和这些节点之间的灵活隧道迁移,由中央控制器管理。即使对于大规模云,这种横向扩展的设计也肯定能胜任。然而,我们在这项工作中表明,由于CPU改进的放缓,CPU核可能会因重击流而过载,这在阿里云中不时被发现。[8]暴露了云网关维护数百万隧道的内存不足问题,提出了商用交换机和基于DPDK的软件转发节点的混合解决方案。然而,他们只是通过使用x86节点存储具有数百万条目的虚拟路由表,来解决内存不足的问题。这样,大部分流量将流入x86节点。相比之下,Sailfish通过将主要表压缩到可编程交换机中来处理大部分流量,仅将少数流量 ( < 0.2 ‰)留给软件。[45]提出了一种通用的软件网关,但转发性能仍然不足以实现云规模部署。
其它的工作[ 16,20,24,30,31,44]构建其他有状态网络设备,如负载均衡器,以及这些设备的一些也采用可编程开关ASIC。他们遇到类似的要维持大型会话状态的内存短缺问题,但提供了截然不同的解决方案。例如,在Silkroad [30]中,通过将5元组哈希成更短的摘要以适应Tofino芯片来压缩连接表。由于负载均衡器根据5元组的精确匹配转发流量,因此哈希确实是一个不错的选择。但是,在云网关中,还需要最长前缀匹配,因此仅通过哈希进行压缩是不够的。TEA[24]提出了一种基于缓存的方法,使用Tofino的片上存储器作为缓存,使用x86节点上的外部DRAM作为备份存储器。片上存储器和DRAM通过快速RDMA通道连接。Sailfish更喜欢预先分配表条目而不是TEA中基于缓存的设计,以避免在极端情况下缓存崩溃和突然性能下降,从而保护网关的稳定性和云服务的可靠性。TEA的另一个不足是它们需要再循环,这导致与我们的解决方案相同的吞吐量成本。
8 结论和未来的工作
我们提出了Sailfish,这是一种基于可编程交换 ASIC 的云规模多租户多服务网关,专为阿里云设计。分享软件网关部署过程中的收获和痛点,并解释为什么我们在2017年转向硬件。为了解决使用Tofino芯片维护大型转发表的内存短缺问题,我们提出硬件和软件协同设计用于表共享、网关集群之间的水平表拆分和单个节点的流水线感知表压缩。与软件网关相比,Sailfish以大致相同的单价实现了显著的单节点性能加速。还提供了经验和教训。
目前,在网关集群之间水平表拆分后,每个网关集群为一些租户携带一部分条目。但是,在实际部署中,我们观察到并非所有租户的条目大部分时间都处于活动状态。以此为契机,未来我们计划构建“N+1”层级XGW-H集群,其中N个前端的缓存集群仅服务于活动条目和1 个备份集群,存储所有租户的条目以处理缓存未命中流量。可以通过数据挖掘或缓存替换来识别活动条目。这样,我们可以使用更少的XGW-H节点来实现更高的处理能力。例如,如果租户的条目只有25%处于活动状态,我们可以构建4个缓存集群(每个集群承载 25% 的活动条目)和1个备份集群(集群承载100%的条目),以提供4倍的性能成本仅为XGW-H节点数量的2倍。
这项工作不会引起任何道德问题。
(全文完)
作者:aliyun
来源:https://mp.weixin.qq.com/s/bstAZT5zH6aGrmrOv8sllA
微信公众号:
相关文章推荐
更多软硬件技术干货请关注软硬件融合专栏。