网易数帆基于DPDK的高性能四层负载均衡实践
目前高性能负载均衡研发的一个流行方案是使用 DPDK(Data Plane Development Kit),这是一个用于包数据处理加速的软件库,使用了网卡用户态驱动、零拷贝、内存 Hugepage 和 Polling 模式等技术。业界基于 DPDK 开发负载均衡主要有两种模式,一是直接在 DPDK 库上自研或者移植负载均衡业务逻辑代码,二是使用 DPDK 作为加速通道加速已有的负载均衡的开源软件。
DPVS 就是一个使用 DPDK 软件库加速 LVS(DPDK+LVS)的高性能负载均衡开源软件。
https://github.com/iqiyi/dpvs
网易数帆选择基于 DPVS 开发新一代四层负载均衡,是因为 DPVS 既解决了 LVS 的性能瓶颈问题,又具备 LVS 的丰富的负载均衡业务逻辑,这使得团队可以把主要精力放在四层负载均衡和云内网络框架适配、运维监控、稳定性和软硬结合提升性能的优化上,而非重复开发负载均衡业务逻辑。
本文从 DPVS 云化场景改造、资源隔离保障系统稳定性、软硬件结合提高系统性能和监控运维功能增强四个方面分享网易数帆高性能四层负载均衡实践之路。
云化场景的核心改造涉及到如下三个方面内容:
云化网络架构适配
健康检查框架设计
图 1.
图 2.
如图 2 所示,网易数帆四层负载均衡外网配置使用 KNI(Kernel NIC Interface)口 bond2.kni 和 DPDK Bond 口 bond2;发布路由的程序 Quagga,Quagga 通信网络依赖于 Linux 内核协议栈,而外网的网卡被 DPVS 用户态程序接管,因此 Quagga 需要将借助 bond2.kni(DPDK 创建的虚拟内核口)口将 BGP 通信流量发给外网路由设备, 而 bond2 口则负责业务流量的收发。
网易数帆四层负载均衡内网配置使用 bond1 口,并根据组网需求建立对应的 VLAN 子接口负责和云网络宿主机网络连通,和 VPC 通信数据需要使用开发的 VXLAN 模块进行 VXLAN 封装和解封装。
VxLAN 模块主要是用来连接云网络和隔离租户的,其属于云化网络连通性中非常关键的部分,所有发给云网络的数据包需要先进行 VxLAN 封装, VxLAN 模块就必须足够的简单和高性能,还要方便控制面程序进行管理配置。
VxLAN 模块在开发之初参考了下面两种方案:
选择 1: 参照 Kernel VxLAN 机制
选择 2: 参照 Openv Switch VxLAN
但是网易数帆最后选择了第 3 种,去除 VxLAN 口的逻辑概念,将 VxLAN 封装和解封装直接使用数据面实现,选择该方法的考虑是以下三点:
性能更优,直接进行 VxLAN 数据包的封装和解封装,在选择后端时候,VxLAN 封装信息就已经具备,这个时候少了一个选择 VxLAN 口的过程;
实现简单,直接流程中实现 VxLAN 封装和解封装就不需要进行 VxLAN 口管理;
逻辑清晰,控制面就不需要关注 VxLAN 口建立和删除。
实现方法命令举例,使用如下方法建立云化场景的后端:
ipvsadm -A -t 60.191.87.35:2022 -s wrr
ipvsadm -a -t 60.191.87.35:2022 -r 192.168.1.178:8700 -T 10.182.6.87-10.182.4.59-5015 -m -w 100
遇到的问题是:
社区 DPVS DNAT 模式只支持单 CPU Core。
社区主推使用 FNAT,DNAT 单 CPU Core 模式使用的人比较少,存在不稳定因素。
社区无法实现 DNAT 模式多 CPU Core,这是社区的一大缺点,其无法使用多 Core 和硬件网卡类型以及架构关联很大。社区实现精妙点是会话(类似于 conntrack)无锁,每 CPU 会话独立管理,为了达到此要求,需要正反向流量使用一个 CPU 处理,因为社区支持的是经典网络的场景,在多业务 CPU CORE DNAT 模式下,从后端回来数据包(反向流量)无法找到固定的特征使用硬件分流一定回到正向流量所在的 CPU。
图 3.
因此云化场景需要解决 VPC 云主机后端回包的问题,网易数帆采用了新型网卡支持的 rte_flow 支持的使用 VxLAN inner dst mac 进行反向流量的硬件分流解决了此问题,具体解决过程描述如图 4 所示:
图 4.
详细过程举例如下:
数据流量发给四层负载均衡外网口时候 rss 到了外网口 q3 队列,在 CPU3 上建立正向会话;
宿主机所在的 SDN 程序会记录该发包五元组对应的源 MAC,后端发给负载均衡流量时候会查询该记录,将 VxLAN inner dst MAC 换成 02:02:00:00:00:03;
四层负载均衡的内网网卡根据 VxLAN inner dst MAC 进行数据分流,根据网卡硬件 rte_flow 配置的策略,将反向流量发给内网口的 q3,从而 CPU3 继续处理。
健康检查是四层负载均衡重要的组成部分,其帮助负载均衡判断业务后端服务是否处于正常工作状态,并且及时剔除不可工作的后端服务,始终让负载均衡的后端服务处于健康状态,确保过负载均衡的业务稳定运行。
云化场景下的后端处于云化网络中,传统的健康检查程序是 socket 程序实现的,socket 不支持 VxLAN 封装,无法连通云网络的后端,因此传统的健康检查程序在云化场景中无法正常工作。为了解决传统健康检查面临的问题,网易数帆提供了健康检查通道技术,帮助健康检查程序连通云网络,传统的健康检查程序零改动的即可检查云化网络的业务后端服务。
图 5.
那么使用 Kernel 协议栈的健康检查程序和位于用户态协议栈的健康检查通道是如何协同工作的呢?如图 5 所示:
健康检查流量被预先配置的路由和预先配置的静态 ARP 信息牵引到 bond2.kni 口,然后这个流量进入到健康检查通道;
检查通道将流量进行 FNAT 转换和进行 VxLAN 封装后发给对应的后端;
从 VPC 后端返回的流量反向运行上述逻辑,控制流量通过 bond2.kni 口发给传统健康检查程序。
这样设计的健康检查机制有如下优点:
健康检查程序透明,健康检查通道是工作在数据面的逻辑层概念,可以理解其为中间代理层,健康检查通道全权代理健康检查程序的检查行为,对健康检查程序透明,传统网络的健康检查程序可直接被使用对云化网络后端进行检查行为;
运维方便,健康检查通道统一管理了所有租户的健康检查行为;
简单,这样的架构,使健康检查通道解耦了健康检查和云化网络连通的逻辑,并且提供接口供控制面使用配置上也非常简单;
通用,这样的结构也适用于经典网络场景。
DPVS 原生框架已经将负载均衡数据处理会话做到 CPU 级别隔离,该机制很大的提升了会话的并发和新建能力,此外原生框架采用了 DPDK 作为底层加速通道,已经提供了基础的高性能框架,但是从实际运行业务的稳定性角度去考虑,其框架上仍有很大的改进点,下面先分析原生框架存在的问题,再给出网易数帆的解决方案。
图 6.
如图 6 所示,将 DPVS 框架按照流量源的差异性分为六个部分;图中使用 6 个序号表示:
健康检查前半部分流量
健康检查后半部分流量
BGP 心跳和配置同步前半部分流量
BGP 心跳和配置同步后半部分流量
控制面配置流量
负载均衡转发业务流量
1 和 3 需要 master cpu0 运行 KNI 模块处理逻辑,将流量从和内核的共享队列中取出;5 也需要 master cpu0 处理用户业务配置,而用户业务配置量级存在突发和不确定性,会独占 master cpu0,导致序号 1 和 3 流量处理不及时而被丢弃。简要描述该问题是,控制面对接模块和 KNI 模块因争抢 master cpu0 计算资源而互相影响。
4 属于 BGP 通信流量的后半部分,该流量社区原生处理是轮询使用各个 slave CPU 将数据包放到绑定的队列中发到外网,BGP 通信流量依赖外网网卡收发队列资源和所有 slave CPU 计算资源;6 属于负载均衡业务流量,业务流量具备非常明显的突发性,当发生流量突发时候,会导致外网网卡的队列资源和 CPU 资源被长时间占用,BGP 通信流量因获取不到队列和 CPU 资源,数据包被丢弃,BGP 产生断连。
2 会用 slave CPU1 和下联口队列 1 将数据包收发给 VPC 后端;6 的业务流量具备明显的突发性,正像在问题 2 中解释的那样,也会使健康检查通道被影响,可能导致健康检查工作异常,进而引发业务无法提供服务。
经过分析,上述三个问题描述了各个流量之间的相互影响和资源依赖,社区原生框架工作在业务流量相对稳定、配置流变动小、普通规模的后端和稳定的组网环境还可以,但是为达到我们产品化级别的稳定性要求,我们还需要做大量工作,所以我们需要使用资源隔离机制保障系统稳定性,网易数帆的解决方法如图 7:
图 7.
控制面对接模块独占 CPU n+1,KNI 模块使用 master cpu0 处理,两个模块 CPU 级别物理独立,解决问题 1;
BGP 通信的流量使用 CPU n 和 qn,业务流量使用 CPU1… CPU n-1 和 q1…qn-1, 两个模块 CPU 和外网队列物理级别独立,解决问题 2;
健康检查通道使用 CPU n、下联口的 qn 队列,业务使用上下联口的 CPU1…CPUn-1、q1…qn-1 ,健康检查通道的流量和业务流量物理资源隔离而不相互影响,解决问题 3;
我们采用的这样的解决方法,解决了提出的原生框架的三个缺陷,但是也引入了新的问题,由图 7 可知,BGP 通信的流量和健康检查通道的流量会共用 CPU n, 共用就会产生影响,但是经过实际极限性能测试,BGP 通信的流量和健康检查通道的流量都不大,一个物理 CPU n 处理完全足够,所以在实际业务中不用担心这个问题。
高性能低成本,一直是数据面开发者追求的目标,我们在启动新负载均衡项目时候,定下的目标是千万级别的并发、千万级别的 PPS、百万级别的新建能力。因为这个级别的性能指标可以帮助公司满足业务需求;DPVS 是 DPDK 和 LVS 的结合体,具备 DPDK 的性能优势(Kernel by-pass 、RX Steering and CPU affinity、Zero Copy、Polling instead of interruptd 等), 继承这些优势,可以帮助实现千万级别的过包率。我们从使用软硬结合机制提高业务最关注的并发能力和业务秒杀场景所需要的新建能力。
会话无锁是并发和新建能力所需要的核心技术。这块我们创新的新开发了 DNAT 模式,使用网卡硬件分流(例如:rss 和 rte_flow)和后端 SDN 软件的设计可以把一个会话的正反向流量都在一个 CPU core 处理,这样分在不同 CPU core 上的会话互不影响,会话之间也就不需要加锁了。上文中 Dnat 模式实现已经讲述了这一点。
除了使用上面介绍的网卡的硬件分流 rss 和 rte_flow 外,还使用网卡卸载了 VxLAN 数据包的内层 L4 的 Checksum 计算,我们下一步计划使用 Mellanox 25G CX5 网卡的 VxLAN 和 Qos 硬件卸载功能进一步提升新建能力和 PPS 能力。
监控运维能力是负载均衡组件的硬实力的代表,我们基于网易内部业务实践运维需求,这块做了大量的工作,下面简要描述下,后续会出文专门对监控运维进行讨论。
业务维度:新增 VIP 级别统计,精确到负载均衡的后端级别,额外开发 VIP 维度的各个连接数统计、VIP Qos 丢包统计、后端级别的连接数统计等 ;
CPU 维度:精确到 CPU 级别,CPU 维度的业务计数(并发连接数、丢包、等);
系统维度:查看 CPU 使用率,丢包率统计,定位丢包发生位置点确认是否是 DVPS 导致业务问题等手段 ;
有了上述多维度的监控,通过业务资源维度的参考,当业务产生异常时候,能够清楚反映到监控的指标中,且经过业务和资源维度的对比,可以确定问题发生的模块,以及该问题发生在哪个数据面 CPU 是否和网卡有关系等。
日志手段是组件的基础能力,在日志能力上,我们进行了分模块和日志分级别方式来提升日志记录的灵活性;不同的场景和模块可进行日志开启动作,并且指定特定模块的日志级别。
目前,网易数帆以 DPVS 为框架完成的新一代高性能的负载均衡已经稳定运行一年多,支撑网易内部网易传媒、网易云音乐、网易严选等各大业务方,各项性能指标都符合预期,其中新建连接能力达到百万级别,并发连接能力千万级别满足了业务需求,这是网易数帆拥抱开源,结合现有云计算架构和业务落地的一次有意义的实践,此外我们在功能和监控运维痛点解决上也做了大量设计工作,这个后续再讨论。
刘勤龙,网易杭州研究院资深云计算开发工程师,7 年服务端开发和优化经验,负责网易数帆四层负载均衡数据面设计,参与网易轻舟服务网格性能优化,目前专注于轻舟云原生 Serverless 平台底层的开发和优化工作。主要关注 Kubernetes、Istio、Knative、Cilium 等技术领域。
张晓龙,网易技术委员会委员,网易数帆轻舟业务部技术总监,2012 年浙江大学博士毕业后加入网易杭州研究院,负责基础设施研发 / 运维至今。在虚拟化、网络、容器、大规模基础设施管理以及分布式系统等技术架构有多年经验,当前主要兴趣点在云原生技术方向。
公司内部已经有一套 Hive 离线数仓,如今业务对实时性提出了更高的需求,但又不希望在 Hive 之外从头新建一套实时数仓、导致重复开发,怎么办?8 月 10 日晚上 20:00,阿里巴巴技术专家李劲松现身 InfoQ《公开课》直播间,详细介绍如何借助 Flink 解决 Hive 流批一体准实时数仓的难题,实现更高效、合理的资源配置。
点个在看少个 bug 👇