PF_RING的多种负载均衡方法

2020-08-21 10:55:53 浏览数 (1)

1.简介

负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。在使用PF_RING时根据为了提高效率我们可以采用对种方式对流量进行分区或分流从而实现负载均衡。 根据打开设备的方式不同我们可以将PF_RING分为标准的PF_RING,和PF_RING ZC两种模式,对于标准的PF_RING我们可以利用RSS多队列技术和PF_RING 内核实现的实现的名为内核集群的机制PF_RING Cluster (Kernel)这两种方法来实现负载均衡。对于PF_RING ZC模式同样可以使用基于硬件的RSS多队列技术实现负载均衡。同时还可以使用zbalance(在PF_RING / userland / examples_zc中)使用多线程或使用zbalance_ipc(在PF_RING / userland / examples_zc中)的多进程的方式来实现负载均衡。

2.标准PF_RING的负载均衡

2.1.RSS负载均衡

使用单个流来处理来自网络适配器的流量需要单个CPU内核才能跟上入口速率。在高速率下,由于每个数据包可用的CPU周期数量有限,即使是轻量级的流量处理,这也成为瓶颈。只要我们的应用程序设计为可与多个线程或进程一起使用并在多个CPU内核上运行,则在一个流中将来自单个接口的流量平均分配到多个流(又称为通道或队列)中,同时保持流的连续性通常是扩展性能的最佳选择。 RSS的使用方法见文章怎样在PF_ring上使用RSS实现网络流量负载均衡

2.2.PF_RING Cluster (Kernel)

由于并非所有网络适配器都具有RSS支持,因此可以在硬件中的多个RX队列之间分配负载,因此PF_RING内核模块实现了一种名为集群的机制,可以跨进程对流量进行分区和负载均衡。这意味着打开PF_RING套接字的不同应用程序可以将它们绑定到特定的群集ID(通过pfring_set_cluster),以加入该集群并分别分析一部分数据包。集群策略中指定了跨集群套接字划分数据包的方式。默认策略是按流(即,属于同一5元组<proto,ip src / dst,端口src / dst>的所有数据包),但是有一些选项。这样,属于同一流的所有数据包将进入同一应用程序,这样流量保持一致,因此保留了应用程序逻辑。

代码语言:javascript复制
pfcount -i eth1 -c 10 -H 5

(注意:内核群集不能与ZC驱动程序结合使用,因为ZC是一项绕过内核的技术。)

3.PF_RING ZC 负载均衡

3.1.RSS负载均衡

这里的RSS多队列负载均衡方法与上文相同,只用打开设备方式有所不同。 标准PF_RING:

代码语言:javascript复制
sudo ./pfcount -i eth1@0

ZC PF_RING:

代码语言:javascript复制
sudo ./zcount -i zc:eth1@0

其中eth1@0表示打开eth1接口的0队列

3.2.多线程负载均衡

zbalance(在PF_RING / userland / examples_zc中)是一个示例应用程序,能够捕获来自一个或多个接口的流量,并负载均衡到多个使用者线程的数据包。

代码语言:javascript复制
 sudo ./zbalance -i eno1 -c 10 -m 1 -r 0 -g 1:2

其中: -i 可以同时打开多个接口使用逗号进行分离如: -i eth1,eth2 -r 0 表示将平衡器线程绑定到核心0, -g 1:2 就表示将两个进程分别绑定到核心1,2。

可以使用命令:

代码语言:javascript复制
cat /proc/cupinfo

查看CPU信息

3.3.多进程负载均衡

在某些情况下,RSS无法用于流量负载平衡,原因是: 1)它并不总是可用(例如,如果您不使用英特尔适配器) 2)在某些用例中,它不够灵活,需要自定义分发功能(例如,像GTP这样的隧道流量) 3)当需要将相同的流量传递到不同的应用程序,但是我们使用ZC锁定网络接口时(我们不能有多个应用程序同时从同一接口捕获流量) 4)当需要将相同的流量传递到不同的应用程序,但每个应用程序需要不同数量的流时(例如,我们希望将流量负载均衡到4个nProbe实例以生成Netflow,并为1个n2disk实例进行流量记录) 在上述情况下,可以使用ZC通过软件分发代替RSS,或者在ZC API之上编写自定义应用程序,或者利用随PF_RING分发的 zbalance_ipc应用程序。zbalance_ipc是一个进程,可用于捕获来自一个或多个接口的流量,并对多个使用方进程进行负载均衡。请注意,为了使用zbalance_ipc,应禁用RSS。 来自2个接口的流量聚合以及使用基于IP的哈希值对2个进程进行负载平衡的示例:

代码语言:javascript复制
zbalance_ipc -i zc:eth1,zc:eth2 -n 2 -m 1 -c 10

其中: -n指定出口队列的数量 -m选择哈希函数 -c指定ZC集群ID 这个简单的示例创建2个流。为了从这些流中捕获流量,可以同时使用标准PF_RING API或ZC API。使用标准PF_RING API的使用者应用程序可以将每个流作为标准接口打开,并将名称zc: @ (例如zc:10 @ 0和zc:10 @ 1)传递给pfring_open API 。pfcount示例:

代码语言:javascript复制
pfcount -i zc:10@0
pfcount -i zc:10@1

为了充分利用灵活的ZC API并使用零复制,使用ZC API的使用者应用程序可以直接通过pfring_zc_ipc_attach_queue API 打开附加到队列ID的每个流。zcount_ipc的示例:

代码语言:javascript复制
zcount_ipc -c 10 -i 0
zcount_ipc -c 10 -i 0

这里: -c 是zbalance_ipc中指定的集群ID -i 是队列ID

更多解决方案

0 人点赞