所使用的KCP-GO:https://github.com/yzslab/kcp-go
原README:点击此处查阅
高RTT的网络,TCP的三次握手、慢启动是非常影响体验的机制。
150ms RTT,使用BBR拥塞控制且网络0丢包的情况下,慢启动到100Mbps至少需要2s,500Mbps至少5s,到1Gbps至少10s。
如果没有BBR,情况则更为糟糕:至少8s才能到100Mbps。
而KCP的多路复用、非退让流控正好消除了TCP的这两个缺点。
-
--iocopybuf
KCP流与TCP流之间互拷数据的缓冲区大小,默认4096,带宽较大时提高此数值可提高传输速度,特别是发送端
-
--irtobackoff
超时重传的初始退让,即在“RTO + (RTO >> irtobackoff)”才开始第一次超时重传,启用退让可显著提高带宽利用率,建议置1或2
-
--irtobthresh
少于多少个数据包时,不应用初始退让,即一个RTO后就立刻重传
-
--noearlyretran
关闭Early Retransmit,可提高带宽利用率,减少数据包重发
-
计算BDP
BDP = 带宽 * RTT
RTT可通过ping测量。
例如500 Mbps带宽,150ms RTT,那么:
BDP = 500 / 8 * 1024 * 1024 * 0.15
-
计算窗口大小
KCP的窗口以数据包数量表示:
窗口大小 = BDP / MTU
如果上下下不对等,需要分别单独计算
-
调大发送端qdisc的flow limit(详见:UDP SndbufErrors & ENOBUFS)
一般在服务端系统调整,对客户端来说,不一定要调整,例如客户端以下行为主,上行带宽使用较低,可跳过此步
# interface="eth0" # 改成与KCPTUN通讯所通过的网卡名 # tc qdisc del dev ${interface} root # tc qdisc add dev ${interface} root fq limit 20000 flow_limit 256
-
把接收端的rmem_max调整为BDP的两倍
一般在客户端系统调整,对服务端来说,不一定要调整,如果服务端以上行为主,下行带宽使用较低,可跳过此步
编辑/etc/sysctl.conf,在其中加入:
net.core.rmem_max=33554432 # 32MB
然后运行:
# sysctl -p
注意不要调整net.core.wmem_max,大带宽下会出现反效果,保持默认值212992即可
请自行按需调整参数(特别是wnd,buf、key):
# server_linux_amd64 \
--target 127.0.0.1:80 \
--listen 0.0.0.0:80 \
--mode manual \
--nodelay 1 \
--interval 10 \
--resend 2 \
--nc 1 \
--mtu 1350 \
--nocomp \
--crypt salsa20 \
--datashard 0 \
--parityshard 0 \
--sndwnd 发送窗口 \
--rcvwnd 接收窗口 \
--sockbuf 至少一个BDP \
--smuxbuf 至少一个BDP \
--key 密钥 \
--iocopybuf 65535 \
--irtobackoff 1 \
--irtobthresh 256 \
--noearlyretran
请自行按需调整参数(特别是wnd,buf、key):
# client_linux_amd64 \
--remoteaddr server:80 \
--localaddr :8088 \
--mode manual \
--nodelay 1 \
--interval 10 \
--resend 2 \
--nc 1 \
--mtu 1350 \
--nocomp \
--crypt salsa20 \
--datashard 0 \
--parityshard 0 \
--sndwnd 发送窗口 \
--rcvwnd 接收窗口 \
--sockbuf 至少一个BDP \
--smuxbuf 至少一个BDP \
--key 密钥 \
--iocopybuf 8192 \
--irtobackoff 1 \
--irtobthresh 256 \
--noearlyretran
-
根据丢包情况,决定是否启用FEC
上面给的服务端与客户端的两个示例参数是没有启用FEC的,如果丢包率较高,请调整--datashard与--parityshard启用FEC,至于多少合适,根据丢包率、以及反复调整测试确定
-
调整发送/接收窗口
为什么还需要调整?一开始不是计算好了吗?
跑的带宽越大,RTT会越高,所以实际的BDP,会比一开始计算的理论值要大,这个具体值,需自行反复调整测试去确定,记得同时更新rmem_max的值。
注意窗口不要调得太大,如果超出接收端的带宽,会有反效果。