在DPVS中实现流量控制


基本信息

版本支持

已实测版本:

  • DPVS-1.8.2-with-DPDK-17.11.2
  • DPVS-1.9.0-with-DPDK-20.11.1
  • DPVS-1.9.2-with-DPDK-20.11.1

上述三个版本对 tc 的配置命令并无差异,文中的配置命令均可受用。

能力支持

以上策略不局限于仅在 Ingress 或 Egress 单向流量配置,也可在同一个流量策略中实现双向组合控制。

基本概念

实现方式

DPVS的限速是通过 TC(Traffic Control) 的机制实现的,Traffic Control是一组在网络接口上排队传输/接收数据包的机制和操作。其中包括排队(enqueuing)、流控策略(policing)、分类(classifying)、调度(scheduling)、塑形(shaping)和丢包(dropping)等操作。

主要用途介绍:

  • Policing:流量控制机制,常用于网络边界,以确保对等方不会消耗超过其分配带宽的流量。
  • Classifying:分组机制,将数据包分离到不同的处理方式,可能是不同的输出队列中。
  • Scheduling:排程机制,将数据包在特定队列的输入和输出之间排列(或重新排列)。
  • Shaping:塑形机制,将数据包在输出队列中延迟传输,以满足所需的输出速率。
  • Dropping:丢弃机制,将数据包完全丢弃。

在DPVS上的实现机制

DPVS通过两种TC对象(QSchCls)实现上述流量控制机制。DPVS 的 TC 框架是基于每个逻辑核(lcore)实现的,以避免多线程竞争条件造成的性能损失。每个 Qsch 必须是根 Qsch 或现有 Qsch 的一个子 Qsch ,并且根 Qsch 必须连接到 DPVS 设备。DPVS TC支持以下设备类型:

  • 物理设备
  • 绑定(bonding)设备
  • VLAN设备

目前不支持隧道设备。支持出站(egress)和入站(ingress)流量,但需要注意的是,入站流量很难受限,因为它主要由网络通信的对等端决定。

扩展说明:

此处的出站和入站都是相对于 DPVS 而言的,而在实际场景中,如果站在 RS 的视角来看这里的出站和入站,那么应该是:

  • 出站: 即 RS 的流入/下载
  • 入站: 即 RS 的流出/上传

基本上,Qsch由一个或多个队列、一组用于队列的操作以及一些流量统计成员组成。Qsch可以作为 根Qsch 安装到 DPVS 接口设备中,也可以作为 子Qsch 集成到现有的 Qsch 中。根Qsch接收其连接设备的所有传入/传出流量,而 非根Qsch 只能从其 父Qsch 接收流量。Qsch可以分为两种不同的类型——出站Qsch和入站Qsch,以执行传输到或从 DPVS 设备接收的数据包的流量控制策略。

Cls是一种分类器,由一组用于将流量分类到不同 Qsch (队列调度器/规则)的操作组成。Cls必须附加到现有的 Qsch 规则上,并在 Cls 匹配到的数据包后,会由 Qsch 规则来决定后续操作。DPVS支持两种分类的目标操作:丢弃(drop)或加入 子Qsch (queue)。不允许将流量分类到非子Qsch(例如孙子Qsch)中。基于性能考虑,数据包仅会排入最后匹配的 Qsch 中,而不是对前序 Qsch 规则逐个匹配。这意味着,如果 Qsch 被层次化配置,并且网络数据包从 根Qsch 到 叶Qsch 匹配所有 Cls,那么数据包将直接被加入到 叶Qsch 中,而不必一个接一个地经过。

每个 Cls 只能处理一种指定的数据包类型。DPVS Cls支持三种数据包类型–IPv4、IPv6和Vlan。Cls支持优先级。如果有两个或多个 Cls 附加到一个 Qsch 上,并且它们都匹配 Qsch 中的数据包,则采用具有最高优先级的 Cls 的分类结果。

Qsch 对象

DPVS TC 实现了四个 Qsch 对象 – pfifobfifopfifo_fasttbf。原则上,它们与 Linux TC 的对应项几乎相同。

pfifo,bfifo

FIFO 意味着“先进先出” ( First-In, First-Out ) ,它只是在收到数据包后尽快传输数据包,并按照数据包接收的顺序排队。

然而,一个真正的 FIFO Qsch 必须有一个大小限制(缓冲区大小),以防止队列溢出。DPVS实现了两个基本的 FIFO Qsch : 一个基于字节(bytes),另一个基于数据包(packets)。无论使用哪种类型的 FIFO,其队列大小都由参数 limit 来定义。

对于 pfifo,单位被理解为数据包(packets),对于 bfifo,单位被理解为字节(bytes)。

pfifo_fast

基于传统的 FIFO Qsch,pfifo_fast Qsch 也提供了一些优先级设置。它提供了三个不同的频段(单独的FIFO)来分离流量。

最高优先级的流量(交互式流量)被放置在频段0 (FIFO 0) 中,并优先得到服务。同样地,如有频段2 (FIFO 2) 的数据包需要出队(流出),则需要等待频段1 (FIFO 1) 处理完其所有排队中的现有数据包。

因此,通常建议将 pfifo_fast 作为根 Qsch。(支持优先级和分离流量的设计,有助于提高网络性能和用户体验,对于多数应用场景已经足够。)

而对于 pfifo_fast 队列,用户没有任何可配置项。关于 priomap 和使用 ToS 比特位的详细信息,请参见文档中的 pfifo-fast 部分。

tbf

TBF 是“令牌桶过滤器”(Token Bucket Filter)的缩写,因为它是建立在 token 和 buckets 之上。它简单地塑造了一个接口上传输的流量。为了限制数据包从一个特定接口的脱队速度,TBF Qsch是一个完美的解决方案。它只是将传输的流量减慢到指定的速率。只有当有足够的令牌可用时,数据包才会被传输。否则,数据包将被推迟。以这种方式延迟数据包将在数据包的往返时间中引入一个人工延迟。

TBF QSch可以有以下参数:

  • rate: 速率参数,单位是 bps,可能会加上 k、m、g 等的 SI 单位后缀(1000进制),最大值为 4 Gbps。
  • burst: 桶大小参数,单位是 bytes。这是可用令牌的最大字节数,通常需要根据速率设置较大的 burst 值。
  • limit/latency: limit 表示可以等待令牌变得可用的队列中的最大字节数,latency 表示在 TBF 中一个数据包最大可以等待的时间,单位分别为 bytes 和 ms 。
  • peakrate: 可选参数,表示桶的最大耗尽速率,单位是 bps,可能会加上 k、m、g 等的 SI 单位后缀。
  • mtu: 可选参数,表示 peakrate 桶的大小,单位是 bytes 。

Cls对象

match

Cls match 规则由两部分组成:模式(pattern)和目标(target)。生产环境中,每个来自 Qsch 的数据包都会与模式进行比较,如果匹配,它们的处理方式将由目标的策略决定。

在配置 模式(pattern) 中,需要考虑一个数据流中的以下五个属性:

  • Protocol: 协议,包括: TCP, UDP, ICMP.
  • Source ip-port range: 源IP的端口范围,数据包的源IP地址和端口的可接受范围。
  • Dest ip-port range: 目的IP的端口范围,数据包的目标IP地址和端口的可接受范围。
  • Ingress device: 入站设备,接收数据包的设备,仅用于入口流量。
  • Egress device: 出站设备,数据包被发送的设备,仅适用于出口流量。

在实际配置中,可以省略上述 pattern 中的一个或多个属性,省略的属性在匹配时会被忽略。

例如: pattern 'tcp,from-192.168.0.1:1-1024,oif-dpdk0' 表示匹配源IP地址为 192.168.0.1,源端口在11024之间,从 DPVS dpdk0 接口发出的 TCP 数据包。

而对于 Cls target 配置有两种策略:Qsch或Drop,具体如下:

  • 前者(Qsch): 将匹配的数据包分类到指定 Qsch 的队列中,且目标 Qsch 必须是 Cls 所附加到的 Qsch 的子级。
  • 后者(Drop): 仅丢弃匹配的数据包。

功能介绍

基本命令

export PATH=/usr/local/dpvs-1.9.2/bin:$PATH

# 开启 egress 限速
dpip link set dpdk0 tc-egress on

# 添加 200Mbps 带宽限制,突发可达240Mpbs的限速规则
dpip qsch add dev dpdk0 root tbf rate 200m burst 2400000 latency 1ms

# 查看 dpdk0 流量调度器(qdisc)信息
dpip qsch show dev dpdk0

# 查看 dpdk0 根流量调度器下的分类器(cls)信息
dpip cls show dev dpdk0 qsch root

# 查看 dpdk0 分类器 ID 为 1 的分类器信息
dpip cls show dev dpdk0 qsch 1:

# 修改限速20Mbps,突发30Mbps
dpip qsch change dev dpdk0 root tbf rate 20m burst 240000 latency 1ms

# 删除限速规则
## 注意: 如有多层规则,那么需要对每层规则手动删除
dpip qsch del dev dpdk0 root tbf
dpip qsch del dev dpdk0 root pfifo_fast
dpip qsch del dev dpdk0 handle 1:0 parent root
dpip qsch del dev dpdk0 handle 10:0 parent 1:0

关键语法说明:

  • rate : 带宽限制,单位(bits/s), 支持 SI 制式(1000进)单位 (k, m, g),例如: 10k, 20m, 1g
  • burst : 突发速率,单位(Bps|Bytes/s),例如可以理解为最大突发可达: xxMB/s
  • 上述两者相互制约:
    • 最大 burst 决定最大带宽,假设 rate 设置为 200mburst 设置为 2000000 (约1.9MB),此时最大带宽约为 67Mbps .
    • 最大 rate 制约 burst ,假设 rate 设置为 100mburst 设置为 20000000 (约19MB),此时最大带宽约为 200Mbps .
  • qsch : 表示网口的排队调度器设置,包括 根排队调度器子排队调度器
    • 根排队调度器是整个调度器层次结构的最上层,它控制整个端口的调度和限速。
    • 子排队调度器是根排队调度器的下一级,它控制端口接收到的特定流量的调度和限速。
    • 例如,如果要为特定 IP 地址或端口号配置不同的服务质量(QoS),可以为其创建子排队调度器。
  • qsch root : 表示网口根排队调度器的分类规则,即指定哪些流量将被发送到子排队调度器进行进一步处理。
  • qsch 1: : 表示网口 qsch 1 的子排队调度器的分类规则,即指定哪些流量将被发送到 qsch 1 进行进一步处理。需要注意的是,这里的 qsch 1: 中的冒号(:)表示所有 qsch 1 的子排队调度器,而不是 qsch 1 本身。

限速配置中,可能实际速率会低于限速值,此时可适时调整。

以下,将基于打流实验进行简单的限速配置介绍。

基准速度

基于iperf3打流进行带宽测试。

Keepalived配置

仅展示关键配置。

local_address_group laddr_g1 {
        192.168.7.185 dpdk0
}

local_address_group laddr_g2 {
        192.168.7.186 dpdk0
}

virtual_server 192.168.7.182 12334 {
        delay_loop 3   # 执行RS健康检测间隔,单位: 秒
        lb_algo rr
        lb_kind FNAT
        protocol TCP
        syn_proxy
        laddr_group_name laddr_g1    # 从这个转发组ID与RS建连
        # 如果所有RS检测失败,则运行脚本
        quorum_down /etc/keepalived/check_rs.sh

        real_server 192.168.7.27 12334 {
                weight 100
                TCP_CHECK {
                        connect_timeout 3
                        nb_sock_retry 2
                        delay_before_retry 3
                        connect_port 80
                }
        }

}

virtual_server 192.168.7.182 12335 {
        delay_loop 3
        lb_algo rr
        lb_kind FNAT
        protocol TCP
        syn_proxy
        laddr_group_name laddr_g1
        quorum_down /etc/keepalived/check_rs.sh

        real_server 192.168.7.27 12335 {
                weight 100
                TCP_CHECK {
                        connect_timeout 3
                        nb_sock_retry 2
                        delay_before_retry 3
                        connect_port 80
                }
        }

}

virtual_server 192.168.7.183 12335 {
        delay_loop 3
        lb_algo rr
        lb_kind FNAT
        protocol TCP
        syn_proxy
        laddr_group_name laddr_g2
        quorum_down /etc/keepalived/check_rs.sh

        real_server 192.168.7.95 12335 {
                weight 100
                TCP_CHECK {
                        connect_timeout 3
                        nb_sock_retry 2
                        delay_before_retry 3
                        connect_port 80
                }
        }
}

IPVS关系

Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.7.182:12334 rr
  -> 192.168.7.27:12334           FullNat 100    0          0
TCP  192.168.7.182:12335 rr
  -> 192.168.7.27:12335           FullNat 100    0          0
TCP  192.168.7.183:12335 rr
  -> 192.168.7.95:12335           FullNat 100    0          0

iPerf3命令

服务端
iperf3 -s -p 12334 -i 1
客户端
# 测试客户端上传,DPVS端下载,RS端下载
iperf3 -c 192.168.7.182 -p 12334 -t 10

结果输出

# 客户端上传
# iperf3 -c 192.168.7.182 -p 12334 -t 10
Connecting to host 192.168.7.182, port 12334
[  4] local 192.168.7.53 port 59896 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  93.6 MBytes   785 Mbits/sec
[  4]   1.00-2.00   sec  98.2 MBytes   824 Mbits/sec
[  4]   2.00-3.00   sec  92.6 MBytes   777 Mbits/sec
[  4]   3.00-4.00   sec  95.5 MBytes   801 Mbits/sec
[  4]   4.00-5.00   sec  96.3 MBytes   808 Mbits/sec
[  4]   5.00-6.00   sec  97.5 MBytes   818 Mbits/sec
[  4]   6.00-7.00   sec  97.9 MBytes   821 Mbits/sec
[  4]   7.00-8.00   sec  96.1 MBytes   807 Mbits/sec
[  4]   8.00-9.00   sec  94.6 MBytes   793 Mbits/sec
[  4]   9.00-10.00  sec  91.7 MBytes   769 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec   954 MBytes   800 Mbits/sec                  sender
[  4]   0.00-10.00  sec   954 MBytes   800 Mbits/sec                  receiver

# ---
# 客户端下载
# iperf3 -c 192.168.7.182 -p 12334 -t 10 -R
Connecting to host 192.168.7.182, port 12334
Reverse mode, remote host 192.168.7.182 is sending
[  4] local 192.168.7.53 port 59944 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  89.6 MBytes   751 Mbits/sec
[  4]   1.00-2.00   sec  90.4 MBytes   758 Mbits/sec
[  4]   2.00-3.00   sec  87.8 MBytes   736 Mbits/sec
[  4]   3.00-4.00   sec  88.2 MBytes   739 Mbits/sec
[  4]   4.00-5.00   sec  90.8 MBytes   761 Mbits/sec
[  4]   5.00-6.00   sec  87.1 MBytes   731 Mbits/sec
[  4]   6.00-7.00   sec  90.9 MBytes   763 Mbits/sec
[  4]   7.00-8.00   sec  87.6 MBytes   735 Mbits/sec
[  4]   8.00-9.00   sec  92.5 MBytes   776 Mbits/sec
[  4]   9.00-10.00  sec  90.5 MBytes   759 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   896 MBytes   751 Mbits/sec    0             sender
[  4]   0.00-10.00  sec   896 MBytes   751 Mbits/sec                  receiver

iperf Done.

可得 RS 的基准带宽:

  • 下行约为 800Mbps
  • 上行约为 751Mbps

出站限速-Egress

整体限速

该限速方法是针对整个 dpdk 网卡进行限速,如果有需要针对多个 VIP、RS 限速需求,应该采取”分类限速”。

设置限速

双向限速

开启限速
  • 将限速设置为 200Mbps .

针对 dpdk0 网卡开启限速

cd /usr/local/dpvs-1.9.2/bin
./dpip link set dpdk0 tc-egress on
./dpip qsch add dev dpdk0 root tbf rate 200m burst 20000000 latency 1ms
查看当前限速策略
./dpip qsch show dev dpdk0

# >>>
qsch tbf root dev dpdk0 parent 0: flags 0x0 cls 0 rate 200.00Mbps burst 20000000B limit 25000B
结果输出
# 客户端上传速率
iperf3 -c 192.168.7.182 -p 12334 -t 10
# >>>
Connecting to host 192.168.7.182, port 12334
[  4] local 192.168.7.53 port 53672 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  37.4 MBytes   314 Mbits/sec
[  4]   1.00-2.00   sec  19.6 MBytes   164 Mbits/sec
[  4]   2.00-3.00   sec  28.1 MBytes   236 Mbits/sec
[  4]   3.00-4.00   sec  18.9 MBytes   158 Mbits/sec
[  4]   4.00-5.00   sec  22.5 MBytes   189 Mbits/sec
[  4]   5.00-6.00   sec  27.0 MBytes   227 Mbits/sec
[  4]   6.00-7.00   sec  20.3 MBytes   170 Mbits/sec
[  4]   7.00-8.00   sec  20.6 MBytes   173 Mbits/sec
[  4]   8.00-9.00   sec  26.3 MBytes   220 Mbits/sec
[  4]   9.00-10.00  sec  19.1 MBytes   160 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec   240 MBytes   201 Mbits/sec                  sender
[  4]   0.00-10.00  sec   240 MBytes   201 Mbits/sec                  receiver

iperf Done.

# ---
# 客户端下载速率
iperf3 -c 192.168.7.182 -p 12335 -t 10 -R
# >>>
Connecting to host 192.168.7.182, port 12335
Reverse mode, remote host 192.168.7.182 is sending
[  4] local 192.168.7.53 port 56984 connected to 192.168.7.182 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.01   sec  37.5 MBytes   313 Mbits/sec
[  4]   1.01-2.00   sec  26.1 MBytes   220 Mbits/sec
[  4]   2.00-3.00   sec  19.5 MBytes   163 Mbits/sec
[  4]   3.00-4.00   sec  26.0 MBytes   219 Mbits/sec
[  4]   4.00-5.00   sec  22.7 MBytes   190 Mbits/sec
[  4]   5.00-6.00   sec  21.5 MBytes   180 Mbits/sec
[  4]   6.00-7.00   sec  23.9 MBytes   201 Mbits/sec
[  4]   7.00-8.00   sec  20.3 MBytes   170 Mbits/sec
[  4]   8.00-9.00   sec  25.2 MBytes   212 Mbits/sec
[  4]   9.00-10.00  sec  19.0 MBytes   159 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   242 MBytes   203 Mbits/sec  708             sender
[  4]   0.00-10.00  sec   242 MBytes   203 Mbits/sec                  receiver

iperf Done.

平均带宽均在 200Mbps 左右,验证生效。

调整限速
  • 将限速设置为 30Mbps .
    ./dpip qsch change dev dpdk0 root tbf rate 30m burst 3000000 latency 1ms
    ./dpip qsch show dev dpdk0
    
    # >>>
    qsch tbf root dev dpdk0 parent 0: flags 0x0 cls 0 rate 30.00Mbps burst 3000000B limit 3750B
结果输出

客户端发起打流,验证限速结果

# 客户端上传速率
iperf3 -c 192.168.7.182 -p 12334 -t 10
# >>>
Connecting to host 192.168.7.182, port 12334
[  4] local 192.168.7.53 port 53837 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  5.24 MBytes  43.8 Mbits/sec
[  4]   1.00-2.00   sec  4.37 MBytes  36.8 Mbits/sec
[  4]   2.00-3.00   sec  3.35 MBytes  28.1 Mbits/sec
[  4]   3.00-4.00   sec  3.36 MBytes  28.2 Mbits/sec
[  4]   4.00-5.00   sec  3.39 MBytes  28.4 Mbits/sec
[  4]   5.00-6.00   sec  3.43 MBytes  28.7 Mbits/sec
[  4]   6.00-7.00   sec  3.41 MBytes  28.7 Mbits/sec
[  4]   7.00-8.00   sec  3.42 MBytes  28.5 Mbits/sec
[  4]   8.00-9.00   sec  3.38 MBytes  28.4 Mbits/sec
[  4]   9.00-10.00  sec  3.41 MBytes  28.6 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec  36.8 MBytes  30.8 Mbits/sec                  sender
[  4]   0.00-10.00  sec  36.6 MBytes  30.7 Mbits/sec                  receiver

iperf Done.

# ---
# 客户端下载速率
iperf3 -c 192.168.7.182 -p 12335 -t 10 -R
# >>>
Connecting to host 192.168.7.182, port 12335
Reverse mode, remote host 192.168.7.182 is sending
[  4] local 192.168.7.53 port 57333 connected to 192.168.7.182 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  5.90 MBytes  49.3 Mbits/sec
[  4]   1.00-2.00   sec  2.98 MBytes  25.0 Mbits/sec
[  4]   2.00-3.00   sec  3.79 MBytes  31.8 Mbits/sec
[  4]   3.00-4.00   sec  3.05 MBytes  25.6 Mbits/sec
[  4]   4.00-5.01   sec  3.76 MBytes  31.6 Mbits/sec
[  4]   5.01-6.00   sec  3.02 MBytes  25.4 Mbits/sec
[  4]   6.00-7.00   sec  3.80 MBytes  32.0 Mbits/sec
[  4]   7.00-8.00   sec  3.02 MBytes  25.3 Mbits/sec
[  4]   8.00-9.00   sec  3.13 MBytes  26.4 Mbits/sec
[  4]   9.00-10.00  sec  3.69 MBytes  30.9 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec  36.6 MBytes  30.7 Mbits/sec  1940             sender
[  4]   0.00-10.00  sec  36.2 MBytes  30.3 Mbits/sec                  receiver

iperf Done.
持续流量过程中调整限速
  • 在持续的流量中,将限速从 200Mbps 调整为 50Mbps 再调整回 200Mbps,验证过程是否有影响。
结果输出
iperf3 -c 192.168.7.182 -p 12334 -t 15

# >>>
Connecting to host 192.168.7.182, port 12334
[  4] local 192.168.7.53 port 54238 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  35.0 MBytes   294 Mbits/sec
[  4]   1.00-2.00   sec  28.6 MBytes   240 Mbits/sec
[  4]   2.00-3.00   sec  18.6 MBytes   156 Mbits/sec
[  4]   3.00-4.00   sec  20.2 MBytes   170 Mbits/sec
[  4]   4.00-5.00   sec  28.1 MBytes   235 Mbits/sec
[  4]   5.00-6.00   sec  8.72 MBytes  73.3 Mbits/sec
[  4]   6.00-7.00   sec  5.73 MBytes  48.1 Mbits/sec
[  4]   7.00-8.00   sec  5.83 MBytes  48.9 Mbits/sec
[  4]   8.00-9.00   sec  3.97 MBytes  33.2 Mbits/sec
[  4]   9.00-10.00  sec  5.83 MBytes  49.0 Mbits/sec
[  4]  10.00-11.00  sec  5.77 MBytes  48.3 Mbits/sec
[  4]  11.00-12.00  sec  37.3 MBytes   313 Mbits/sec
[  4]  12.00-13.00  sec  19.3 MBytes   162 Mbits/sec
[  4]  13.00-14.00  sec  28.6 MBytes   241 Mbits/sec
[  4]  14.00-15.00  sec  19.0 MBytes   159 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-15.00  sec   271 MBytes   151 Mbits/sec                  sender
[  4]   0.00-15.00  sec   271 MBytes   151 Mbits/sec                  receiver

验证有效。

删除限速
./dpip qsch del dev dpdk0 root tbf

分类限速

该限速方法可以根据应用场景进行分类限速,支持对多个 RS 配置不同限速规则。

场景说明
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.7.182:12334 rr synproxy
  -> 192.168.7.27:12334           FullNat 100    0          0
TCP  192.168.7.182:12335 rr synproxy
  -> 192.168.7.27:12335           FullNat 100    0          0
TCP  192.168.7.183:12335 rr synproxy
  -> 192.168.7.95:12335           FullNat 100    0          0

接下来,将针对上述的 RS 设置不同的限速策略:

  • 双向不限速
    • 所有 RS12334 端口: 双向不限速
  • 针对RS限制出站
    • 192.168.7.27:12335: 限制出站 200Mbps (即 RS 下载带宽)
    • 192.168.7.95:12335: 限制出站 250Mbps (即 RS 下载带宽)
配置方式
# 开启egress限速
./dpip link set dpdk0 tc-egress on

# 编写分级限速策略
./dpip qsch add dev dpdk0 root pfifo_fast
./dpip qsch add dev dpdk0 handle 1:0 parent root bfifo limit 10000000
./dpip qsch add dev dpdk0 handle 10:0 parent 1:0 pfifo limit 100000
./dpip qsch add dev dpdk0 handle 20:0 parent 1:0 tbf rate 80m burst 8000000 latency 2ms
./dpip qsch add dev dpdk0 handle 30:0 parent 1:0 tbf rate 150m burst 15000000 latency 2ms

# 分级策略
./dpip cls add dev dpdk0 qsch root handle 0:1 match pattern 'tcp,oif=dpdk0' target 1:

# 针对RS地址分类
./dpip cls add dev dpdk0 qsch 1: handle 1:1 match pattern 'tcp,to=:12334,oif=dpdk0' target 10:
./dpip cls add dev dpdk0 qsch 1: handle 1:2 match pattern 'tcp,to=192.168.7.27:12335,oif=dpdk0' target 20:
./dpip cls add dev dpdk0 qsch 1: handle 1:3 match pattern 'tcp,to=192.168.7.95:12335,oif=dpdk0' target 30:
查看限速策略
# 整体限速
./dpip qsch show dev dpdk0
# >>>
qsch pfifo_fast root dev dpdk0 parent 0: flags 0x0 cls 1 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qsch tbf 30: dev dpdk0 parent 1: flags 0x0 cls 0 rate 150.00Mbps burst 15000000B limit 37500B
qsch tbf 20: dev dpdk0 parent 1: flags 0x0 cls 0 rate 80.00Mbps burst 8000000B limit 20000B
qsch pfifo 10: dev dpdk0 parent 1: flags 0x0 cls 0 limit 100000
qsch bfifo 1: dev dpdk0 parent root flags 0x0 cls 3 limit 10000000

# ---
# 分级策略
./dpip cls show dev dpdk0 qsch 1:
# >>>
cls match 1:1 dev dpdk0 qsch 1: pkttype 0x0800 prio 0 TCP,to=0.0.0.0-0.0.0.0:12334-12334,oif=dpdk0 target 10:
cls match 1:2 dev dpdk0 qsch 1: pkttype 0x0800 prio 0 TCP,to=192.168.7.27-192.168.7.27:12335-12335,oif=dpdk0 target 20:
cls match 1:3 dev dpdk0 qsch 1: pkttype 0x0800 prio 0 TCP,to=192.168.7.95-192.168.7.95:12335-12335,oif=dpdk0 target 30:
结果输出
# 192.168.7.182:12334不限速
iperf3 -c 192.168.7.182 -p 12334 -t 10
# >>>
Connecting to host 192.168.7.182, port 12334
[  4] local 192.168.7.53 port 65415 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.01   sec  87.9 MBytes   727 Mbits/sec
[  4]   1.01-2.00   sec  84.8 MBytes   722 Mbits/sec
[  4]   2.00-3.00   sec  92.4 MBytes   775 Mbits/sec
[  4]   3.00-4.00   sec  84.7 MBytes   710 Mbits/sec
[  4]   4.00-5.00   sec  96.8 MBytes   812 Mbits/sec
[  4]   5.00-6.00   sec  90.5 MBytes   759 Mbits/sec
[  4]   6.00-7.00   sec  95.5 MBytes   801 Mbits/sec
[  4]   7.00-8.00   sec  90.2 MBytes   756 Mbits/sec
[  4]   8.00-9.00   sec  88.1 MBytes   739 Mbits/sec
[  4]   9.00-10.00  sec  96.7 MBytes   811 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec   908 MBytes   761 Mbits/sec                  sender
[  4]   0.00-10.00  sec   908 MBytes   761 Mbits/sec                  receiver

iperf Done.

# ---
# 192.168.7.182:12335限速80Mbps
iperf3 -c 192.168.7.182 -p 12335 -t 10
# >>>
Connecting to host 192.168.7.182, port 12335
[  4] local 192.168.7.53 port 65441 connected to 192.168.7.182 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  14.7 MBytes   123 Mbits/sec
[  4]   1.00-2.00   sec  9.42 MBytes  78.9 Mbits/sec
[  4]   2.00-3.00   sec  9.37 MBytes  78.5 Mbits/sec
[  4]   3.00-4.00   sec  9.80 MBytes  82.3 Mbits/sec
[  4]   4.00-5.00   sec  7.62 MBytes  64.1 Mbits/sec
[  4]   5.00-6.00   sec  9.23 MBytes  77.1 Mbits/sec
[  4]   6.00-7.00   sec  10.1 MBytes  85.3 Mbits/sec
[  4]   7.00-8.00   sec  9.39 MBytes  78.9 Mbits/sec
[  4]   8.00-9.00   sec  9.40 MBytes  78.6 Mbits/sec
[  4]   9.00-10.00  sec  9.31 MBytes  78.4 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec  98.4 MBytes  82.5 Mbits/sec                  sender
[  4]   0.00-10.00  sec  98.3 MBytes  82.4 Mbits/sec                  receiver

iperf Done.

# ---
# 192.168.7.183:12335限速150Mbps
iperf3 -c 192.168.7.183 -p 12335 -t 10
# >>>
Connecting to host 192.168.7.183, port 12335
[  4] local 192.168.7.53 port 65473 connected to 192.168.7.183 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  30.8 MBytes   258 Mbits/sec
[  4]   1.00-2.00   sec  17.3 MBytes   145 Mbits/sec
[  4]   2.00-3.00   sec  17.1 MBytes   144 Mbits/sec
[  4]   3.00-4.00   sec  17.1 MBytes   144 Mbits/sec
[  4]   4.00-5.00   sec  17.0 MBytes   142 Mbits/sec
[  4]   5.00-6.00   sec  17.3 MBytes   145 Mbits/sec
[  4]   6.00-7.00   sec  17.2 MBytes   144 Mbits/sec
[  4]   7.00-8.00   sec  17.1 MBytes   144 Mbits/sec
[  4]   8.00-9.00   sec  17.2 MBytes   145 Mbits/sec
[  4]   9.00-10.00  sec  17.2 MBytes   144 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec   185 MBytes   155 Mbits/sec                  sender
[  4]   0.00-10.00  sec   185 MBytes   155 Mbits/sec                  receiver

策略生效。

删除限速策略
./dpip qsch del dev dpdk0 root pfifo_fast
./dpip qsch del dev dpdk0 handle 1:0 parent root bfifo limit 10000000
./dpip qsch del dev dpdk0 handle 10:0 parent 1:0 pfifo limit 100000
./dpip qsch del dev dpdk0 handle 20:0 parent 1:0 tbf rate 80m burst 8000000 latency 2ms
./dpip qsch del dev dpdk0 handle 30:0 parent 1:0 tbf rate 150m burst 15000000 latency 2ms

除了限速,还可以实现 Ingress 方向控制、针对源IP或目标IP的访问控制与 UDP 协议分流转发相关配置等,详见: DPVS Traffic Control (TC)


最佳实践

基于Egress实现出入站分类限速

分类限速

场景说明
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.7.182:12334 rr synproxy
  -> 192.168.7.27:12334           FullNat 100    0          0
TCP  192.168.7.182:12335 rr synproxy
  -> 192.168.7.27:12335           FullNat 100    0          0
TCP  192.168.7.183:12335 rr synproxy
  -> 192.168.7.95:12335           FullNat 100    0          0

针对上述的 VIP 和 RS 设置不同的限速策略:

  • 双向不限速
    • 192.168.7.27:12334: 双向不限速
  • 针对VIP限制
    • 192.168.7.182:12335: 出站/上传 150Mbps (即 VIP 上传带宽)
    • 192.168.7.183:12335: 出站/上传 80Mbps (即 VIP 上传带宽)
  • 针对RS限制
    • 192.168.7.27:12335: 限制入站 200Mbps (即 RS 下载带宽)
    • 192.168.7.95:12335: 限制入站 250Mbps (即 RS 下载带宽)
配置方式
添加限速
export PATH=/usr/local/dpvs-1.9.2/bin:$PATH

dpip link set dpdk0 tc-egress on
dpip qsch add dev dpdk0 root pfifo_fast
dpip qsch add dev dpdk0 handle 1:0 parent root bfifo limit 10000000
dpip qsch add dev dpdk0 handle 10:0 parent 1:0 pfifo limit 100000
dpip qsch add dev dpdk0 handle 20:0 parent 1:0 tbf rate 200m burst 21000000 latency 2ms
dpip qsch add dev dpdk0 handle 30:0 parent 1:0 tbf rate 250m burst 26000000 latency 2ms
dpip qsch add dev dpdk0 handle 40:0 parent 1:0 tbf rate 150m burst 16000000 latency 2ms limit 30000000
dpip qsch add dev dpdk0 handle 50:0 parent 1:0 tbf rate 80m burst 9000000 latency 2ms limit 8000

dpip cls add dev dpdk0 qsch root handle 0:1 match pattern 'tcp,oif=dpdk0' target 1:
dpip cls add dev dpdk0 qsch 1: handle 1:1 match pattern 'tcp,to=:12334,oif=dpdk0' target 10:
dpip cls add dev dpdk0 qsch 1: handle 1:2 match pattern 'tcp,to=192.168.7.27:12335,oif=dpdk0' target 20:
dpip cls add dev dpdk0 qsch 1: handle 1:3 match pattern 'tcp,to=192.168.7.95:12335,oif=dpdk0' target 30:
dpip cls add dev dpdk0 qsch 1: handle 1:4 match pattern 'tcp,from=192.168.7.182:12335,oif=dpdk0' target 40:
dpip cls add dev dpdk0 qsch 1: handle 1:5 match pattern 'tcp,from=192.168.7.183:12335,oif=dpdk0' target 50:
查看策略
dpip qsch show dev dpdk0
dpip cls show dev dpdk0 qsch root
dpip cls show dev dpdk0 qsch 1:
删除策略
dpip qsch del dev dpdk0 root pfifo_fast
dpip qsch del dev dpdk0 handle 1:0 parent root
dpip qsch del dev dpdk0 handle 10:0 parent 1:0
dpip qsch del dev dpdk0 handle 20:0 parent 1:0
dpip qsch del dev dpdk0 handle 30:0 parent 1:0
dpip qsch del dev dpdk0 handle 40:0 parent 1:0
dpip qsch del dev dpdk0 handle 50:0 parent 1:0
验证测试
Uploading to 192.168.7.182:12334 ...
# iperf3 -c 192.168.7.182 -p 12334 -t 10
Connecting to host 192.168.7.182, port 12334
[  4] local 192.168.7.53 port 61150 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  91.0 MBytes   763 Mbits/sec
[  4]   1.00-2.00   sec  95.6 MBytes   802 Mbits/sec
[  4]   2.00-3.00   sec  93.3 MBytes   782 Mbits/sec
[  4]   3.00-4.00   sec  82.7 MBytes   693 Mbits/sec
[  4]   4.00-5.00   sec  84.5 MBytes   709 Mbits/sec
[  4]   5.00-6.00   sec  84.5 MBytes   709 Mbits/sec
[  4]   6.00-7.00   sec  96.8 MBytes   812 Mbits/sec
[  4]   7.00-8.00   sec  86.0 MBytes   722 Mbits/sec
[  4]   8.00-9.00   sec  96.5 MBytes   810 Mbits/sec
[  4]   9.00-10.00  sec   100 MBytes   839 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec   911 MBytes   764 Mbits/sec                  sender
[  4]   0.00-10.00  sec   911 MBytes   764 Mbits/sec                  receiver

iperf Done.

# ---
Downloading from 192.168.7.182:12334 ...
# iperf3 -c 192.168.7.182 -p 12334 -t 10 -R
Connecting to host 192.168.7.182, port 12334
Reverse mode, remote host 192.168.7.182 is sending
[  4] local 192.168.7.53 port 61161 connected to 192.168.7.182 port 12334
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  94.3 MBytes   791 Mbits/sec
[  4]   1.00-2.00   sec  90.2 MBytes   756 Mbits/sec
[  4]   2.00-3.00   sec  92.5 MBytes   776 Mbits/sec
[  4]   3.00-4.00   sec  94.3 MBytes   791 Mbits/sec
[  4]   4.00-5.00   sec  95.6 MBytes   802 Mbits/sec
[  4]   5.00-6.00   sec  92.8 MBytes   778 Mbits/sec
[  4]   6.00-7.00   sec  92.2 MBytes   774 Mbits/sec
[  4]   7.00-8.00   sec  95.7 MBytes   802 Mbits/sec
[  4]   8.00-9.00   sec  94.5 MBytes   793 Mbits/sec
[  4]   9.00-10.00  sec  95.4 MBytes   801 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   938 MBytes   787 Mbits/sec    0             sender
[  4]   0.00-10.00  sec   938 MBytes   787 Mbits/sec                  receiver

iperf Done.

# ---
Uploading to 192.168.7.182:12335 ...
# iperf3 -c 192.168.7.182 -p 12335 -t 10
Connecting to host 192.168.7.182, port 12335
[  4] local 192.168.7.53 port 61179 connected to 192.168.7.182 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  38.6 MBytes   324 Mbits/sec
[  4]   1.00-2.01   sec  22.8 MBytes   191 Mbits/sec
[  4]   2.01-3.01   sec  20.1 MBytes   168 Mbits/sec
[  4]   3.01-4.01   sec  27.3 MBytes   229 Mbits/sec
[  4]   4.01-5.01   sec  18.7 MBytes   157 Mbits/sec
[  4]   5.01-6.00   sec  27.3 MBytes   230 Mbits/sec
[  4]   6.00-7.00   sec  20.1 MBytes   169 Mbits/sec
[  4]   7.00-8.00   sec  23.4 MBytes   197 Mbits/sec
[  4]   8.00-9.00   sec  22.2 MBytes   186 Mbits/sec
[  4]   9.00-10.00  sec  20.2 MBytes   170 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec   241 MBytes   202 Mbits/sec                  sender
[  4]   0.00-10.00  sec   241 MBytes   202 Mbits/sec                  receiver

iperf Done.

# ---
Downloading from 192.168.7.182:12335 ...
# iperf3 -c 192.168.7.182 -p 12335 -t 10 -R
Connecting to host 192.168.7.182, port 12335
Reverse mode, remote host 192.168.7.182 is sending
[  4] local 192.168.7.53 port 61188 connected to 192.168.7.182 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  31.1 MBytes   260 Mbits/sec
[  4]   1.00-2.00   sec  17.5 MBytes   146 Mbits/sec
[  4]   2.00-3.00   sec  17.3 MBytes   145 Mbits/sec
[  4]   3.00-4.00   sec  17.5 MBytes   148 Mbits/sec
[  4]   4.00-5.00   sec  13.3 MBytes   111 Mbits/sec
[  4]   5.00-6.00   sec  19.7 MBytes   166 Mbits/sec
[  4]   6.00-7.00   sec  17.4 MBytes   146 Mbits/sec
[  4]   7.00-8.00   sec  17.4 MBytes   146 Mbits/sec
[  4]   8.00-9.00   sec  17.3 MBytes   145 Mbits/sec
[  4]   9.00-10.00  sec  17.4 MBytes   145 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   186 MBytes   156 Mbits/sec   38             sender
[  4]   0.00-10.00  sec   186 MBytes   156 Mbits/sec                  receiver

iperf Done.

# ---
Uploading to 192.168.7.183:12335 ...
# iperf3 -c 192.168.7.183 -p 12335 -t 10
Connecting to host 192.168.7.183, port 12335
[  4] local 192.168.7.53 port 61197 connected to 192.168.7.183 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  45.8 MBytes   383 Mbits/sec
[  4]   1.00-2.00   sec  27.2 MBytes   228 Mbits/sec
[  4]   2.00-3.00   sec  30.1 MBytes   253 Mbits/sec
[  4]   3.00-4.00   sec  32.3 MBytes   271 Mbits/sec
[  4]   4.00-5.00   sec  11.6 MBytes  97.6 Mbits/sec
[  4]   5.00-6.00   sec  28.1 MBytes   236 Mbits/sec
[  4]   6.00-7.00   sec  32.4 MBytes   272 Mbits/sec
[  4]   7.00-8.00   sec  33.2 MBytes   277 Mbits/sec
[  4]   8.00-9.00   sec  36.7 MBytes   309 Mbits/sec
[  4]   9.00-10.00  sec  29.3 MBytes   246 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec   307 MBytes   257 Mbits/sec                  sender
[  4]   0.00-10.00  sec   306 MBytes   257 Mbits/sec                  receiver

iperf Done.

# ---
Downloading from 192.168.7.183:12335 ...
# iperf3 -c 192.168.7.183 -p 12335 -t 10 -R
Connecting to host 192.168.7.183, port 12335
Reverse mode, remote host 192.168.7.183 is sending
[  4] local 192.168.7.53 port 61205 connected to 192.168.7.183 port 12335
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec  15.2 MBytes   128 Mbits/sec
[  4]   1.00-2.00   sec  6.29 MBytes  52.8 Mbits/sec
[  4]   2.00-3.00   sec  12.4 MBytes   103 Mbits/sec
[  4]   3.00-4.00   sec  10.5 MBytes  88.5 Mbits/sec
[  4]   4.00-5.00   sec  6.21 MBytes  52.3 Mbits/sec
[  4]   5.00-6.00   sec  12.5 MBytes   105 Mbits/sec
[  4]   6.00-7.00   sec  8.83 MBytes  73.8 Mbits/sec
[  4]   7.00-8.00   sec  6.21 MBytes  52.1 Mbits/sec
[  4]   8.00-9.00   sec  12.4 MBytes   104 Mbits/sec
[  4]   9.00-10.00  sec  8.86 MBytes  74.0 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   103 MBytes  86.1 Mbits/sec  4590             sender
[  4]   0.00-10.00  sec  99.5 MBytes  83.4 Mbits/sec                  receiver

iperf Done.

策略生效。

小结

本次操作的限速规则可以理解成下面的一种树状结构:

root qdisc
 └─ pfifo_fast qdisc (dev dpdk0 parent 0:1)
     ├─ tbf qdisc (dev dpdk0 parent 1:2)
     │   └─ cls match (dev dpdk0 parent 1:2 qdisc 10:) (pkttype 0x0800 prio 0 TCP,to=0.0.0.0-0.0.0.0:12334-12334,oif=dpdk0) (target 10:)
     ├─ tbf qdisc (dev dpdk0 parent 1:2)
     │   └─ cls match (dev dpdk0 parent 1:2 qdisc 20:) (pkttype 0x0800 prio 0 TCP,to=192.168.7.27-192.168.7.27:12335-12335,oif=dpdk0) (target 20:)
     ├─ tbf qdisc (dev dpdk0 parent 1:3)
     │   └─ cls match (dev dpdk0 parent 1:3 qdisc 30:) (pkttype 0x0800 prio 0 TCP,to=192.168.7.95-192.168.7.95:12335-12335,oif=dpdk0) (target 30:)
     ├─ tbf qdisc (dev dpdk0 parent 1:4)
     │   └─ cls match (dev dpdk0 parent 1:4 qdisc 40:) (pkttype 0x0800 prio 0 TCP,from=192.168.7.182-192.168.7.182:12335-12335,oif=dpdk0) (target 40:)
     ├─ tbf qdisc (dev dpdk0 parent 1:5)
     │   └─ cls match (dev dpdk0 parent 1:5 qdisc 50:) (pkttype 0x0800 prio 0 TCP,from=192.168.7.183-192.168.7.183:12335-12335,oif=dpdk0) (target 50:)
     ├─ pfifo qdisc (dev dpdk0 parent 1:6) (limit 100000)
     └─ bfifo qdisc (dev dpdk0 parent 0:5) (cls 5 limit 10000000)

从上面的结构可以看出,即便流量方向都是 egress ,但你仍可以根据 fromto 的方式实现出入站的限速策略。

写在最后

生产环境中,应该将 ingressegress 分开配置,但本篇主要仅做功能介绍,仅提供一个配置思路。


Reference

Traditional Elements of Traffic Control

Linux TC(Traffic Control)框架原理解析 - CSDN

TC限速实践 - 简书


文章作者: NesTeaLin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 NesTeaLin !
  目录