Closed ZezhongWang closed 5 years ago
本项目开篇就说了,不是为流量设计的(每秒钟多少 KB),是为流速设计的(RTT)。
完整的 udp 传输系统有很多需要注意的地方,以其你自己写 kcp 实现,不如去测试下 kcptun
kcptun 就是用 kcp 实现的, kcp都快不了更不用说 kcptun。
然后关于 RTT 这点也是有问题的。 加上了 ackNodelay,fastRetrans 这些策略确实可能原理上是能更稍微有一些提升,但是 30%-40% 的RTT的提升这个数据是哪里来的??
RTT 本身很大程度上是取决于本身网络链路状态,类似于网络的一个基本属性。测试数据也显示并不能有什么提升。
我比较对你实现的bbr拥塞控制有兴趣,有patch吗
我比较对你实现的bbr拥塞控制有兴趣,有patch吗
现在实现的还比较粗略。其实就是在kcp-go的基础上加了个类似于 tcp_bbr.c 中的 model,然后再在收到ack 的时候update model,目前是自己开了个 private 写了测试下,因为直接用的别人的代码而且写的有点随意就没 public
我举个例子,一个运动员专业是跑步,你的测试方法是叫他去跟人比赛游泳。
还是老话,KCP 优化的是 Latency/RTT (XX ms),所以你测试的是带宽(KB/s)属于 ”间接测试“,并不是 ”直接测试“。KCP 设计目的是比 TCP 更低的 Latency/RTT,而不是更好的带宽利用率或者 KB/s,那么:
那么为什么经常有用 kcp 加速 VPS 翻墙和音视频推流呢?因为一般你上一下 youtube 或者传递下音视频流,带宽远没有达到物理上限(不是你这种 iperf 要榨干网络的传输法),比如公网高峰期 5%-10%的丢包的时候,远距离传输的时候,此时物理带宽的上限远没达到,但是因为延迟和丢包率的存在,导致 tcp 的 latency 极高,KB/s 也上不去,这也是最常见的情况,此时 KCP 的加速效果明显,不管对 Latency 和 KB/s。
理解这个原理你就不会用榨干网络带宽的方式来测试 KB/s 了。
真实产品 100 多万用户同时在线测试出来的,模拟丢包测试出来的,取个平均值。
我自己应用过 KCP 的项目,基本都测试过: https://github.com/skywind3000/kcp/wiki/HISTORY
不止我一个人测试,数个团队分别不同层面测试,结论相同。
RTT 本身很大程度上是取决于本身网络链路状态,类似于网络的一个基本属性。测试数据也显示并不能有什么提升。
你说的 RTT 是物理级别 UDP / ICMP 的 round-trip-time,我指的 RTT 是数据经过 TCP/KCP 之类可靠协议传输走一圈的时间,只要没有触碰到物理带宽上限,当然会比 TCP 快很多,这个数值的测试,KCP 首页末尾也提到了很多,他们的程序和测试环境描述都放在那里,你感兴趣自己去看。
test.cpp 也模拟了不同延迟和丢包情况下,这些策略的开关到底能带来多大的提升。这么明显的区别你但凡看过一下都不会说出 “很大程度上是取决于本身网络链路状态” 这种话来。
为了准确交流,RTT 指代网络物理层的 udp/icmp ping 值,而 Latency 指数据经过可靠协议传输后走一圈的延迟。标准 Latency 测试要怎么测呢?不是简单弄个 KB/s,你先要画一张表:
丢包/延迟 | 10ms | 50ms | 100ms | 200ms |
---|---|---|---|---|
0% | .. | .. | .. | .. |
5% | .. | .. | .. | .. |
10% | .. | .. | .. | .. |
15% | .. | .. | .. | .. |
20% | .. | .. | .. | .. |
然后针对每一种情况,计算出一个平均延迟来,比如下面这张图,就是网络延迟 300 毫秒,丢包率 20% 的情况,多种不同的协议传输延迟(Latency)分布图:
横坐标是延迟,纵坐标是该协议有百分之多少的样本延迟小于等于横坐标代表的值。
举个例子:
而青色方块(P4),是未经任何可靠协议处理的,裸 UDP RTT 时间,你可以理解成网络 RTT 的物理下限,协议做的好,就是无限制的靠近这条青色方块线,协议做的差就会远离。
在上面这个图中,就所有样本的平均延迟而言,KCP 472ms 同时 TCP 是 698ms,而最大延迟,KCP 比 TCP 低很多倍(记不得了)。
对每种不同网络情况,都做这么一张图,都得到一个平均延迟和最大延迟,填到上面的表上去,30%-40%就是这么测试出来的,搞明白了么?
你说的数据统计确实很多paper中也是这么做的。不过这么做我还有一个问题。
一切都是基于: 在所有被测试协议在相同的网络丢包率相同的情况下
但是实际网络情况并不是这样的,就比如说,在相同的网络, TCP 和 UDP 以相同的网络速率(例如 1MB/s)发送数据, 实际网络中UDP 丢包率明显会比 TCP 大。
比如我以 1MB/s 速率发送数据:
// UDP 发包丢包率为 3.30%
>.\iperf-go.exe -c 104.224.137.244 -b 1 -proto kcp -sw 128
10:31:20.612 0 ▶ INFO 001 Go-logging init finish
Iperf started:
addr:104.224.137.244 port:5201 proto:rudp interval:1000 duration:10 NoDelay:false burst:false BlockSize:4096 StreamNum:1
RUDP settting: sndWnd:128 rcvWnd:512 writeBufSize:4096Kb readBufSize:4096Kb noCongestion:true flushInterval:10 dataShards:0 parityShards:0
Connect to server 104.224.137.244:5201 succeed.
[ ID] Interval Transfer Bandwidth RTT Retrans Retrans(%) Lost(%) Early(%) Fast(%)
[ 0] 0.00-1.00 sec 0.98 MB 7.88 Mb/s 164.0ms 26 3.35% 3.35% 0.00% 0.00%
[ 0] 1.00-2.00 sec 0.98 MB 7.81 Mb/s 164.0ms 15 1.98% 1.98% 0.00% 0.00%
[ 0] 2.00-3.00 sec 0.97 MB 7.78 Mb/s 164.0ms 30 3.89% 3.89% 0.00% 0.00%
[ 0] 3.00-4.03 sec 0.93 MB 7.44 Mb/s 174.0ms 25 3.41% 3.41% 0.00% 0.00%
[ 0] 4.03-5.00 sec 0.98 MB 7.88 Mb/s 165.0ms 66 8.09% 8.09% 0.00% 0.00%
[ 0] 5.00-6.00 sec 0.95 MB 7.62 Mb/s 166.0ms 13 1.76% 1.76% 0.00% 0.00%
[ 0] 6.00-7.00 sec 0.97 MB 7.75 Mb/s 165.0ms 35 4.53% 4.53% 0.00% 0.00%
[ 0] 7.00-8.00 sec 0.96 MB 7.69 Mb/s 164.0ms 4 0.54% 0.54% 0.00% 0.00%
[ 0] 8.00-9.00 sec 0.99 MB 7.94 Mb/s 165.0ms 24 3.08% 3.08% 0.00% 0.00%
[ 0] 9.00-10.00 sec 0.96 MB 7.72 Mb/s 164.0ms 16 2.13% 2.13% 0.00% 0.00%
- - - - - - - - - - - - - - - - SUMMARY - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth RTT Retrans Retrans(%) Lost(%) Early(%) Fast(%) Recover(%) PktsLost(%) SegsLost(%)
[ 0] 0.00-10.00 sec 9.69 MB 7.75 Mb/s 165.5ms 254 3.30% 3.30% 0.00% 0.00% 0.00% 0.03% 0.03% [SENDER]
// tcp 丢包率为0
>.\iperf-go.exe -c 104.224.137.244 -b 1
10:30:49.166 0 ▶ INFO 001 Go-logging init finish
Iperf started:
addr:104.224.137.244 port:5201 proto:tcp interval:1000 duration:10 NoDelay:false burst:false BlockSize:131072 StreamNum:1
Connect to server 104.224.137.244:5201 succeed.
[ ID] Interval Transfer Bandwidth RTT Retrans
[ 0] 0.00-1.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 1.00-2.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 2.00-3.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 3.00-4.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 4.00-5.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 5.00-6.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 6.00-7.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 7.00-8.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 8.00-9.00 sec 1.00 MB 8.00 Mb/s 0.0ms 0
[ 0] 9.00-10.00 sec 1.12 MB 9.00 Mb/s 0.0ms 0
- - - - - - - - - - - - - - - - SUMMARY - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth RTT Retrans Retrans(%)
[ 0] 0.00-10.00 sec 10.12 MB 8.10 Mb/s NaNms 0 0.00% [SENDER]
目前根据我已知的,这种丢包率的差距跟 ISP 对UDP流量的管控有关(还可能有别的影响因素) 也就是说,在真实的网络中,你通过在网络模拟器(NS)模拟出来的效果并不是像你通过在设定的 ”网络延迟 300 毫秒,丢包率 20% 的情况“ 跑的那么好。
换取话说,如果要真正比较在实际网络中的性能, 丢包率应该在 TCP 与 UDP 之间进行换算(不过这种换算方法目前我也没搞清楚),假设UDP平均丢包率是TCP的两倍(实际情况在触及bottleneck的时候会远大于这个值),那么此时表格就应该变成:
TCP丢包/UDP丢包/延迟 | 10ms | 50ms | 100ms | 200ms |
---|---|---|---|---|
0%/0% | .. | .. | .. | .. |
5%/10% | .. | .. | .. | .. |
10%/20% | .. | .. | .. | .. |
15%/30% | .. | .. | .. | .. |
20%/40% | .. | .. | .. | .. |
所以我认为如果只是单纯地在 NS 上进行数据统计,也应该将丢包率进行换算,否则就只是理想状态下的一个统计。
讨论归讨论(我还是得表达一下对大神的敬意,毕竟我现在是还写不出这样的代码
存在运营商UDP限流,但是大部分应用,比如传点视频这类,远达不到限流的限制。Retrans 衡量丢包率是不对的,因为这是协议算出来的,协议本来就更倾向于判断为:丢包。
30%-40%的latency降低不光是内网模拟丢包实验的结果,更是外网将用户分组,同一时段两组用户用不同的协议对比出来的。
你的问题主要是测试方法从一开始就是间接测试,而不是直接测试,另外是想象成份过大。
就这么着吧,能理解就理解,不能理解就做罢。
我也没时间给你免费讲课了,忙。
收到了,我的测试方法确实存在一些问题,感谢大佬抽出时间答疑
请问一下这周图里的丢包是上或下行丢包20%, 还是上下行丢包各20%(综合丢包的话,就是36%了?)
一下是对于 Kcp-go 的测速结果,但是我觉得C语言实现也会有同样的问题,想来请教一下。
我自己用go语言实现了iperf测速工具, 实现了基本的一些测速功能, 最主要的就是加上了对于自定义应用层协议的扩展, 所以也可以用来对kcp进行更精确地测速.因为 Fast.com 之类的还是涉及到了3个点的传输。
然后一个有趣的现象就是, 对于我自身的网络情况:
在上行情况下,用适当的参数,确实 KCP 的表现会比 TCP 好一些,大约有40%-50%提升 :
但是在下行的情况下(TCP有BBR支持),TCP的表现则好很多,快有 KCP 的一倍。并且我也调整过KCP的一些参数,均未获得较好的效果(例如调整snd_wnd, buffer之类)
通过其他参数可发现, KCP无论上行还是下行情况下丢包率都异常地高(30%,40%以上),再加上early resend的策略的话在下行的report中可以发现,重传的包量甚至已经超过了本身的包量(也就是说平均下来每个包都发了两次多)
这么来看在 UDP 上搭建可靠传输还是值得商榷的,这么高的丢包率可能与ISP对UDP流量的管制有关。
这里还想讨论的就是,
iperf-go 测试工具: https://github.com/ZezhongWang/iperf-go 欢迎使用!