干货 | 携程基于DPDK的高性能四层负载均衡实践

2022-03-18 09:40:36 浏览数 (1)

作者简介

Yellowsea,携程资深技术支持工程师,负责四层负载均衡研发及私有云k8s cloud provider开发,关注Kubernetes、Linux Kernel、分布式系统等技术领域。

前言

在携程的服务流量接入架构中,一般是采用四层负载均衡与七层负载均衡相结合的方式,其中四层负载均衡支撑着业务运行的关键部分。在业务流量不断增长的过程中,不断考验着四层负载均衡的性能及可靠性。由于原硬件四层负载均衡存在成本高、采购周期长、HA工作模式等问题,原有的体系难以满足快速增长的业务需求,迫切需要在开源社区中寻找高性能四层负载均衡软件化的解决方案。

本文主要讲述基于开源的DPVS打造携程的高性能四层软件负载均衡TDLB (Trip.com Dpdk LoadBalancer),其极大的提升了设备的转发性能,具有高可靠、可扩展、易使用等特性。

一、TDLB高性能实现

传统LVS负载均衡的功能与硬件设备类似,但由于其性能存在瓶颈,难以满足携程四层负载均衡服务的实际业务场景需求。DPVS (https://github.com/iqiyi/dpvs) 结合DPDK的特性,解决了LVS的性能瓶颈,同时又能满足原有的负载均衡服务需求。

1.1 DPDK

在内核中,从网卡获取数据包是通过硬件中断模式完成,内核态与用户态的切换耗时,而且切换导致cache命中率下降,影响处理数据包的性能。

在DPDK中采用kernel bypass的设计,通过应用程序主动轮询的方式从网卡获取数据包,使应用程序维持在用户态运行,避免内核态与用户态切换的耗时问题,提升处理数据包时cache的命中率。

1.2 会话无锁

初期的LVS采用全局的会话资源供多个core同时使用,多个core之间会产生资源的竞争,带来了锁的问题。

TDLB主要使用fullnat模式,为了避免core与core之间的资源竞争,我们设计了percore的会话,作为有状态的四层负载均衡必须保证入向流量与出向流量分配至同一个core,出向流量才能匹配上原先建立的会话。

入向流量可以利用RSS将数据包散列至各个队列,而每个core绑定对应的队列,对于相同的数据包 (sip,sport,dip,dport) RSS会被分配至同一core。为了保证出向回程流量还经过原先的core可以为每个core分配不同的SNAT IP,在fullnat模式中,client IP会被转化成SNAT IP,到达server后,server回应报文的目的ip就是原先的SNAT IP,此时可以借助网卡的FDIR (Flow Director) 技术来匹配SNAT IP,将回程报文分配至对应的core,确保数据流的出向流量与入向流量分配至同一core。

1.3 用户源IP透传

在FNAT模式中,后端服务器需要获取真实客户端IP,目前主要有两种方式:

  • TOA:在TCP建连完成后传递的第一个数据包中,加入带有客户端信息的TCP Option字段,以此传递用户源IP,后端服务可以在无感知的情况下获取用户源IP,但是需要在服务器上挂载TOA相应的kernel module。
  • ProxyProtocol:在TCP建连完成后传递的第一个数据包的数据前,加入ProxyProtocol对应的报文,其中包含客户端信息,这部分报文通过单独的一个数据包发送,避免分片的产生,ProxyProtocol可以同时支持TCP及UDP,但是需要在服务的应用层提供ProxyProtocol的支持。

DPVS沿用LVS中的TOA(TCP Option Address)的方式传递用户源IP,TDLB在DPVS的基础上增加了对ProxyProtocol的支持,以此满足不同服务场景的需求。

1.4 日志异步写入

在DPDK原日志存储机制中,当有大量日志需要记录时,单个文件I/O锁带来的耗时将影响各个CPU的数据包处理,严重时将影响控制平面流量并导致BGP连接断开。DPVS在此基础上加入消息处理机制,各个核产生的日志将进入消息队列,由日志处理的核单独处理,保证I/O不会受到锁的影响。

在DPVS框架基础上,技术经过初步的消化吸收,建立了TDLB的雏形。为了适配携程的网络环境、业务场景及需求,进一步提升单机及集群的可靠性,TDLB主要从以下五个方面进行进一步的改造:

  • 集群多活模式
  • 资源隔离
  • 集群配置管理
  • 健康检测策略
  • 多维度监控

二、集群会话同步

在集群多活模式下,服务器的扩缩容会导致路由路径的重新分配,没有会话同步功能支持的情况下,已有的连接会失效并导致应用层超时。这对长连接的应用影响更加明显,影响集群的可用性,无法灵活的扩缩容应对业务高峰。

2.1 同步策略

核与核间的会话信息资源已被隔离,同时入向业务流量是通过RSS进行分配的,所以在集群中服务器网卡RSS配置一致的情况下,同一网卡队列编号对应核的会话信息可以共用。

为了做到多台服务器核与核间的信息交互,为每个核单独分配一个内网IP地址(FDIR),用于转发数据包至后端服务器的同时(SNAT IP),用于会话信息同步的Source Address及Dest Address。

在此基础上,TDLB集群使用的SNAT Pool需要一个连续的网段,每台TDLB服务器分配一个同等大小的子网,同时会利用BGP同时宣告三个子网掩码不同的SNAT Pool网段路由:

  • 网卡对应CPU分配的子网段 (32-log(n/2))
  • 服务器分配的子网段 (32-log(n))
  • TDLB集群的SNAT Pool网段 (32-log(n*m))

以此保证一台TDLB服务器拉出集群后,其他TDLB服务器可以接收到已有连接中RealServer的数据包,保证已有连接不会断开。

1)服务器正常情况

当Client(CIP: 1.1.1.0, CPort: 5000)请求服务(VIP: 1.1.1.1, VPort: 80)时,路由到TDLB 0并通过SNAT IP(LIP: 10.0.0.0, LPort: 6000)转发给RealServer(RIP: 10.0.1.0, RPort: 8080),其中这个TDLB集群对应的SNAT Pool是10.0.0.0/24。

2)服务器异常情况

当TDLB 0拉出集群(停止BGP宣告路由)时,Client的请求被重新路由到了TDLB 3,由于查询到了同步的会话信息,因此使用相同的SNAT IP(10.0.0.0)转发给相同的RealServer(10.0.1.0),RealServer回复请求时被重新路由到了TDLB 1再转发给Client。

3)服务器恢复工作

当TDLB 0拉入集群恢复工作后,原本属于TDLB 0的会话会被重新分配给TDLB 0。

2.2 同步类型

为满足服务器处于不同状态下的会话同步,同步类型分为两种:

  • 增量同步:在新的连接建立时进行,并随着数据的传输保持连接的状态同步
  • 全量同步:在新的服务器加入集群时,需要全量同步会话信息,保证接入流量时不对已有连接产生影响

在支持会话同步的基础上,TDLB集群可以采用多活模式进行灵活的水平扩缩容,一方面可以根据业务的需求调整集群服务器数量降低成本,另一方面可以在用户无感知的情况下完成TDLB集群的维护。

三、资源隔离

3.1 CORE与CORE之间的数据隔离

利用网卡的RSS,FDIR等流控技术,将数据流分配至同一core,保证了core处理数据流时不需要用到全局资源,避免了资源竞争带来锁的问题。处理数据流需要使用的相关资源可以在初始化时,为每个core单独分配资源,利用消息处理机制保证core与core之间的信息同步。

3.2 NUMA架构下CPU数据隔离

目前服务器主要采用NUMA架构,CPU与CPU之间跨NUMA访问数据在一定程度上限制了应用的性能,在TDLB设计的目标中尽可能避免跨NUMA访问数据的情况。

在上述设计中,为了达到会话无锁的目标,会话流量已经被限定在同一个队列、core中,这已经为资源隔离打下了基础。在负载均衡服务处理中,高频访问的资源有网卡配置、VS配置、地址、路由、会话表等,四层的会话处理相关资源已被隔离,网络协议栈中的相关资源与硬件资源相关,因此根据NUMA架构中CPU的数量各分配独立的硬件网卡资源即可,在做到资源隔离的同时,充分利用CPU的工作能力,提高单台服务器的负载能力。

3.3 控制平面与数据平面流量隔离

TDLB的流量主要分成两部分:

  • 控制平面流量:BGP、健康检测及二层信息交互
  • 数据平面流量:负载均衡服务

在初期设计中,控制平面流量需要通过数据平面的相关工作核处理后进入KNI队列中,当业务负载超出阈值时将影响到BGP及健康检测服务,且混杂的流量增加了系统的复杂度,使控制平面的流量难以定位。

对原先的RSS配置进行修改,隔离出一个单独的队列,同时结合FDIR将控制平面流量导入隔离的队列中,实现控制平面与数据平面流量的隔离。

四、集群配置管理

在硬件设备以及LVS的集群管理中,都是通过API的方式与设备交互,进行配置的管理。当集群从主备模式转变为多活模式时,通过多线程的方式一定程度上可以保证配置的下发效率,但被动的配置更新无法保证服务器进入集群提供服务时配置的一致性,且每台服务器独立的API鉴权增加了控制的复杂度。在k8s中的controller及reconcile机制提供了解决方案。

使用etcd存储集群配置,每台TDLB服务器都会启动operator监听相关配置更新产生的事件,并通过etcd的证书鉴权保证配置的有效性。

  • 在更新配置前,API开始监听配置对应key prefix的事件,开启监听后更新etcd中的集群配置
  • 配置更新产生事件,TDLB服务器上的operator捕获事件后进行相应的配置更新操作
  • 更新操作成功完成后,将配置版本回写至etcd相应的key中
  • 配置版本回写产生事件,API监听到事件后进行统计,当集群所有服务器都更新完成,则操作完成

每当TDLB服务启动后,都会与etcd进行配置同步,保证进入集群提供服务时配置的一致性。集群水平扩容服务器时,新进入集群的服务器通过这种同步机制即可完成配置的下发,与服务部署的自动化保证了水平扩缩容的效率,应对业务流量的增长。

五、健康检测策略

当一台负载均衡设备上存在多块网卡时,如果仅从一块网卡发起健康检测,当该网卡线路出现故障时,将影响到整台设备的服务,即网卡线路层面的故障升级到服务器层面。

为了控制网卡单点故障的影响范围,在同一时间,从每块网卡发起健康检测,并且将服务的部分配置按网卡进行分隔,当一条网卡的线路出现故障,仅影响线路对应的服务配置,其他网卡线路依旧正常工作,这样更好地保证了服务器剩余的工作能力。

六、多维度监控

在多活模式的集群中,需要从不同维度进行监控,提高故障的响应效率及定位效率:

  • 集群维度:监控集群整体服务状态
  • 服务器维度:监控单台服务器的服务状态以及集群中服务器间的差异
  • 服务维度:监控每个服务的状态,便于用户对于服务状态的感知
  • CORE维度:监控每个CORE的工作状态,便于集群容量的评估

基于DPDK latency stats设计了CORE与CORE独立的metric计算与存储,从而高效的获取处理数据包耗时以及工作周期耗时的数据,监控单台机器以及整个集群的服务工作状态。

监控数据接入prometheus及grafana,设置了各个维度的监控告警,帮助快速定位故障点。

总结

TDLB作为以DPVS基础框架完成的高性能四层负载均衡软件,稳定运行近两年时间,支撑着携程各项业务。各项性能指标均符合预期,在满足业务需求的同时,大大降低成本,推进了四层负载均衡服务与私有云的接入,这也是拥抱开源社区的回馈。

【推荐阅读】

  • 携程监控系统Hickwall演进之路
  • 高效线上问题排查——套路化和工具化
  • 携程持久化KV存储实践
  • 携程数据库发布系统演进之路

 “携程技术”公众号

  分享,交流,成长

0 人点赞