近日,Facebook开源了Katran,一个四层网络负载均衡器软件包,已经被用在Facebook的网络负载均衡器当中。Katran是一种基于软件的负载均衡解决方案,利用了两项最新的内核工程创新:eXpress Data Path(XDP)和eBPF虚拟机。Katran被部署在Facebook的PoP服务器上,用于提高网络负载均衡的性能和可扩展性,并减少在没有数据包流入时的循环等待。
Facebook面临的挑战
为了管理Facebook的流量,他们部署了一个分布式PoP服务器作为数据中心的代理。鉴于极高的请求量,PoP和数据中心都面临着巨大挑战,比如如何将大量的后端服务器作为单一的虚拟单元提供给外部,以及如何在后端服务器之间高效地分配工作负载。
他们为每个位置分配虚拟IP地址(VIP),发送到VIP的数据包被无缝地分发给后端服务器。在实现分发算法时,需要考虑到后端服务器通常是在应用层处理请求,并且会终结TCP连接。于是网络负载均衡器(通常称为第四层负载均衡器或L4LB)需要负责处理数据包方面的问题。
图1:网络负载均衡器将来自客户端的数据包发送给后端服务器。
对高性能负载均衡器的要求
L4LB的性能对降低延迟和扩展后端服务器来说尤其重要,因为L4LB需要处理每个传入的数据包。L4LB的性能通常通过每秒可以处理的数据包峰值(pps)来衡量。一般来说,工程师们首选基于硬件的解决方案,因为这样可以使用加速器,如专用集成电路(ASIC)或可编程门阵列(FPGA)来减轻主CPU的负担。然而,基于硬件的解决方案有个缺点,就是它限制了系统的灵活性。为了有效满足Facebook的需求,网络负载均衡器必须:
为了满足这些需求,他们设计了一个高性能的软件网络负载均衡器。第一代L4LB基于IPVS内核模块,满足了Facebook四年多的需求。不过,它与其他服务很难共存,特别是后端服务。在第二次迭代中,他们利用eXpress数据路径(XDP)框架和新的BPF虚拟机(eBPF)让软件负载均衡器和其他服务运行在一起。
图2:两代L4LB之间的差别
第一代L4LB:基于OSS软件
第一代L4LB使用了大量的开源组件来实现大部分功能,因此能够在几个月内取代基于硬件的解决方案。该设计有四个主要组成部分:
每个L4LB还将每个5元组保存起来作为查找表,避免重复计算后续数据包的哈希值。这只是一种优化措施,并不会影响到正确性。这种设计符合上述的工作负载要求,但存在一个不足:L4LB和后端服务共存于同一台设备上增加了设备出现故障的可能性。为此,他们在不相关的一组机器上运行L4LB和后端服务。由于L4LB数量比后端服务器少,因此更容易受突发流量负载的影响。
图3:第一代L4LB概览
Katran:重新设计转发面板
Katran就是第二代L4LB,通过完全重新设计转发面板,显著提高之前版本的性能。两项最新的内核工程创新为新设计提供了动力:
第二代系统的总体架构与第一代L4LB相似:首先,ExaBGP向互联网发布特定的Katran实例负责哪个VIP。其次,发往VIP的数据包通过ECMP机制发送到Katran实例。最后,Katran将数据包转发给正确的后端服务器。它们之间的主要区别在于最后一步。
高效的数据包处理:Katran结合使用XDP和BPF程序来转发数据包。在驱动器模式下启用XDP时,数据包处理例程(BPF程序)会在网络接口卡(NIC)收到数据包之后以及在内核截获之前运行。XDP在每个传入数据包上调用BPF程序。如果NIC具有多个队列,则为每个队列并行调用该程序。用于处理数据包的BPF程序是无锁的,并使用单CPU内核版本的BPF映射。因为具备了这种并行性,性能与NIC的RX队列数量呈线性关系。Katran还支持“通用XDP”操作模式(而不是驱动模式),不过需要以牺牲性能为代价。
开销更小且更稳定的哈希:Katran使用Maglev哈希算法的扩展版来选择后端服务器。扩展版哈希算法具备了更好的弹性,能够更均匀的分布负载,可以为不同的后端服务器设置不同的权重。其中最后一项最为重要,他们因此能够轻松处理PoP和数据中心的硬件更新:通过设置适当的权重来更新硬件。计算哈希值的代码体积很小,完全可以放入L1缓存中。
更具弹性的本地状态:Katran在处理数据包和计算哈希值时需要与本地状态表发生交互。他们发现,通常情况下,计算哈希值比查找本地状态表中的5元组更容易,因为在本地状态表中有时候需要遍历到最后一级缓存才能找到目标。为此,他们将查找表实现为LRU缓存。LRU缓存大小可在启动时配置,并作为可调参数,以便在计算和查找之间取得平衡。此外,Katran提供了一个运行时“仅计算”开关,以便在主机发生灾难性内存压力的情况下完全忽略LRU缓存。
RSS封装:接收端伸缩(Received Side Scaling,RSS)是针对NIC的一项重要优化,旨在通过将数据包发送到单独的CPU来均匀地在CPU之间分布负载。不同流中的数据包使用不同的外部IP来封装,但相同流中的数据包总是被分配相同的外部IP。
图4:Katran为高速处理数据包提供了一条快速路径,无需借助内核旁路。
这些特性显著提升了L4LB的性能、灵活性和可扩展性。如果没有数据包流入,Katran几乎不消耗CPU。与内核旁路解决方案(如DPDK)相比,XDP可以让Katran与任何应用程序一起运行,而不会遭受性能损失。现在,Katran与Facebook的PoP后端服务器一起运行,增强了对负载峰值的处理能力和主机故障恢复能力。
其他注意事项
Katran的GitHub地址:https://github.com/facebookincubator/katran
感谢郭蕾对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号:InfoQChina)关注我们。
领取专属 10元无门槛券
私享最新 技术干货