kcptun icon indicating copy to clipboard operation
kcptun copied to clipboard

功能需求: 增加最大发送带宽限制功能

Open sharpbai opened this issue 4 years ago • 5 comments

目前在长肥管道下如果想达到高带宽利用率,存在以下矛盾

在「发送与接收端的RTT」大于「协议处理周期」(即interval参数)时,不存在同一个发送窗口的尺寸,在发送策略为窗口中有数据就应发尽发的策略下,既满足一次性突发传输的速率不超过预设带宽,又能保持持续传输达到预设带宽。

举例:发送端与接收端固有物理带宽均为200mbps,平均RTT为90ms,kcptun的发送周期为20ms, kcptun的mtu设置为1400

为了达成持续发送时窗口容纳BDP的数据,配置发送窗口为1536。但这会造成在突发传输时,20ms内的峰值带宽达到持续传输的(RTT/发送周期)倍数,即4.5倍,实际峰值带宽会达到约900mbps。

一方面,发送数据超过实际带宽对于数据传输延迟造成不利影响,另一方面,这种行为是不被服务商允许的,实际效果是在突发传输后,AWS与ALI/TX的机器间会出现对应端口传输的数据RTT变为1000ms的惩罚措施,该惩罚持续时长为60s。

目前通过tc在发送端机器与接收端机器把发送速度限制到200mbps,同时做20ms的发送平滑措施,没有出现过一次惩罚问题,也没有因此而产生过断流问题。

但这个措施只是保底解决被惩罚的问题,在突发期被tc丢弃的数据会依赖重传,这部分数据会增大其传输延迟。不如直接从源头上控制发送速率,达成更低的传输延迟。这样也更符合KCP的设计目标——为流速优化

所以建议增加最大发送带宽限制功能,针对底层的单个KCP连接,根据配置的最大发送速率决定一次发送的最大数据量,而不是窗口有空间就全部发出去。

如果在kcptun层面,增加配置单个端上连接的最大发送带宽与接收带宽,并在发送时协商,让对端的发送速率匹配到其发送速率与我方接收速率的最低值,则更为方便。

sharpbai avatar Aug 05 '21 07:08 sharpbai

目前在长肥管道下如果想达到高带宽利用率,存在以下矛盾

在「发送与接收端的RTT」大于「协议处理周期」(即interval参数)时,不存在同一个发送窗口的尺寸,在发送策略为窗口中有数据就应发尽发的策略下,既满足一次性突发传输的速率不超过预设带宽,又能保持持续传输达到预设带宽。

举例:发送端与接收端固有物理带宽均为200mbps,平均RTT为90ms,kcptun的发送周期为20ms, kcptun的mtu设置为1400

为了达成持续发送时窗口容纳BDP的数据,配置发送窗口为1536。但这会造成在突发传输时,20ms内的峰值带宽达到持续传输的(RTT/发送周期)倍数,即4.5倍,实际峰值带宽会达到约900mbps。

周期内数据量/周期 = 周期内平均速度。你这个说法有问题,我只发一个包,1400字节,用了 1us,那么带宽是140Gbps,带宽必须有一个相对较长的采样时间来作为分母。

一方面,发送数据超过实际带宽对于数据传输延迟造成不利影响,另一方面,这种行为是不被服务商允许的,实际效果是在突发传输后,AWS与ALI/TX的机器间会出现对应端口传输的数据RTT变为1000ms的惩罚措施,该惩罚持续时长为60s。

目前通过tc在发送端机器与接收端机器把发送速度限制到200mbps,同时做20ms的发送平滑措施,没有出现过一次惩罚问题,也没有因此而产生过断流问题。

但这个措施只是保底解决被惩罚的问题,在突发期被tc丢弃的数据会依赖重传,这部分数据会增大其传输延迟。不如直接从源头上控制发送速率,达成更低的传输延迟。这样也更符合KCP的设计目标——为流速优化

所以建议增加最大发送带宽限制功能,针对底层的单个KCP连接,根据配置的最大发送速率决定一次发送的最大数据量,而不是窗口有空间就全部发出去。

如果在kcptun层面,增加配置单个端上连接的最大发送带宽与接收带宽,并在发送时协商,让对端的发送速率匹配到其发送速率与我方接收速率的最低值,则更为方便。

xtaci avatar Aug 05 '21 08:08 xtaci

周期内数据量/周期 = 周期内平均速度。你这个说法有问题,我只发一个包,1400字节,用了 1us,那么带宽是140Gbps,带宽必须有一个相对较长的采样时间来作为分母。

「带宽必须有一个相对较长的采样时间来作为分母」是对的,所以这里采用的是20ms作为一个周期。

这里存在网卡本身物理速度,如1Gbps, 10Gbps等,实际发送速度不会突破这个值。 因为「网卡物理带宽」一般都高于「购买的预设带宽」,这里才会有「超发」的问题。

实际抓包看,单次发送数据超过20ms「购买的预设带宽」可以承载的数据量的3~4倍以上,可能引起惩罚问题。 如果网络服务商不惩罚,友好的采取接收一定缓冲区突发传输+长期平均固定带宽传输,那延迟增长与丢包总得选一样或者都有一些。

sharpbai avatar Aug 05 '21 09:08 sharpbai

周期内数据量/周期 = 周期内平均速度。你这个说法有问题,我只发一个包,1400字节,用了 1us,那么带宽是140Gbps,带 实际抓包看,单次发送数据超过20ms「购买的预设带宽」可以承载的数据量的3~4倍以上,可能引起惩罚问题。 如果网络服务商不惩罚,友好的采取接收一定缓冲区突发传输+长期平均固定带宽传输,那延迟增长与丢包总得选一样或者都有一些。

他的采样策略是什么,实时带宽如何计算的,这个能给出资料么。

xtaci avatar Aug 08 '21 05:08 xtaci

那得实现一个pacing

agol586 avatar Aug 09 '21 05:08 agol586

他的采样策略是什么,实时带宽如何计算的,这个能给出资料么。

没有明确的资料。 我搜索了下关于流控策略设备的资料,如这个H3C的说明书写的,可以基于一些规则进行速度限制,并在超过限制后可以配置惩罚措施。感觉上这些云主机厂商用的东西应该没有原理上的差别。 然后就具体到了「如何判断超过了带宽」这件事情。根据这个文章的说明,应当是根据令牌桶的原理。 即设立一个大小合适的桶(足以容纳允许的突发数据传输量),然后定时向桶里加入按带宽算出来的令牌,消耗时就减去令牌,没有令牌之后就不能再转发了。 具体到

  • 令牌桶多大
  • 定时粒度是多少

这个确实不清楚,但按理说,应当公网上匹配大量出现在网络上的设备,如Linux主机,Windows机器,iOS/macOS等。一般情况下这些设备的定时粒度不做特别处理也就达到10ms级别。

我自己实践的效果,在服务端和客户端都用tc配置TBF,限制队列长度为20ms(即kcptun的interval,平滑发送数据到kcp下次发送为止,不引入额外延迟。因为Linux默认HZ是100,所以这里平滑发送,实际上也就是把20ms发送一次的数据分成间隔10ms发两次),突发传输长度为20ms按预设带宽200mbps流过的数据量(保证缓冲的数据在理论上不引起排队造成的延迟增大),在200mbps的机器上实测有效解决断流问题。

tc qdisc add dev eth0 root tbf rate 190mbit burst 488kb latency 20ms mpu 64

建议直接按照预设带宽值,根据interval算出每个间隔最大发送多少数据,据此控制单次循环最多发送的数据量即可。 更细粒度的控制,如平滑发送一个间隔内的数据,可能由tc这类的工具来实现会更好。

sharpbai avatar Aug 09 '21 09:08 sharpbai