Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tcpmux 会大幅降低链路速度 #2987

Closed
1 of 11 tasks
shiyunjin opened this issue Jun 17, 2022 · 20 comments · Fixed by #3474
Closed
1 of 11 tasks

tcpmux 会大幅降低链路速度 #2987

shiyunjin opened this issue Jun 17, 2022 · 20 comments · Fixed by #3474

Comments

@shiyunjin
Copy link

Bug Description

仅创建一个tcp内网穿透连接

修改选项 tcp_mux = true

开启tcp_mux 测速得 10-15 Mbps
关闭tcp_mux 测速得 100 Mbps

frpc Version

0.42.0

frps Version

0.42.0

System Architecture

linux/amd64

Configurations

[common]
server_addr = *****
server_port = 3000
token = *****

heartbeat_interval = 3
heartbeat_timeout = 10

tcp_mux = true
pool_count = 1

Logs

No response

Steps to reproduce

No response

Affected area

  • Docs
  • Installation
  • Performance and Scalability
  • Security
  • User Experience
  • Test and Release
  • Developer Infrastructure
  • Client Plugin
  • Server Plugin
  • Extensions
  • Others
@shiyunjin
Copy link
Author

测速方向 frpc客户端(源)->frps服务端(下载)

@shiyunjin
Copy link
Author

hashicorp/yamux#24

@shiyunjin
Copy link
Author

shiyunjin commented Jun 17, 2022

kcptun 2016年的时候使用yamux也出现了同样的问题
xtaci/kcptun#126

@shiyunjin
Copy link
Author

我已经自行将frp中的 yamux 替换为 https://github.com/xtaci/smux

速度已经达到正常水平
20220618021135

在我这里问题解决了,如有觉得必要官方可以也进行替换. (本issues可以随时关闭)

@fatedier
Copy link
Owner

目前不会替换,稳定性比速度更重要,v2 中可能会倾向于使用 QUIC。

@github-actions
Copy link

Issues go stale after 30d of inactivity. Stale issues rot after an additional 7d of inactivity and eventually close.

@hayden-pan
Copy link

我已经自行将frp中的 yamux 替换为 https://github.com/xtaci/smux

速度已经达到正常水平 20220618021135

在我这里问题解决了,如有觉得必要官方可以也进行替换. (本issues可以随时关闭)

经过分析,发现了yamux和smux在速度上存在的区别的可能原因。smux的第一个版本协议里,只有一整个session的接收缓冲区,所有的stream共用,这导致了smux可以减少很多在yamux上使用的缓冲区通信,因为每次的缓冲区通信需要一个TTL时间,所以降低了速度,但是重点来了,这个设计会有一个严重的问题,当某个stream有问题,占用满了整个session缓冲区时,会影响同一个session下的所有stream,所以后来smux开发了v2版本添加了和yamux一样的stream缓冲区控制逻辑,但是如果用户没有特别指定使用v2版本,默认是使用v1版本。所以想问下当时您测试的环境使用的是V2还是V1版本

那么接下来说说我自己在排除这个TTL影响的情况下测试(因为做包含TTL的测试比较麻烦,让我偷懒一下 : ) )
我本地直接复制了yamux的bechmark测试代码(smux没有benchmark代码),因为yamux和smux的对外接口很像,所以基本没有问题,yamux的测试代码是直接在本地内存拷贝模拟的网络IO,所以基本没有延迟,这个测试主要是测试代码的CPU和内存消耗以及操作速度,直接说结论,都是yamux胜出。全部都使用默认配置。

欢迎大家一起讨论

yamux

image

smux(v1)

image

smux(v2)

image

@shiyunjin
Copy link
Author

shiyunjin commented Aug 24, 2022

使用的是smux v1

但是重点来了,这个设计会有一个严重的问题,当某个stream有问题,占用满了整个session缓冲区时,会影响同一个session下的所有stream
你所说的问题我确实也发现了,但是吞吐量对我来说更为重要

所谓的smux v2最后更新时间为2019年,而v1是2021年。

我刚才简单测试了一下smux v2也存在吞吐量低的问题

这个问题不必过于纠结,我自己现在自用的版本已经满足我的需求了。可能对于绝大多数人来说稳定速度更为重要

@hayden-pan
Copy link

使用的是smux v1

但是重点来了,这个设计会有一个严重的问题,当某个stream有问题,占用满了整个session缓冲区时,会影响同一个session下的所有stream

你所说的问题我确实也发现了,但是吞吐量对我来说更为重要

所谓的smux v2最后更新时间为2019年,而v1是2021年。

我刚才简单测试了一下smux v2也存在吞吐量低的问题

这个问题不必过于纠结,我自己现在自用的版本已经满足我的需求了。可能对于绝大多数人来说稳定速度更为重要

我也只是最近在研究这两个库,看到了相关的讨论顺便回复一下

@hayden-pan
Copy link

目前不会替换,稳定性比速度更重要,v2 中可能会倾向于使用 QUIC。

使用QUIC的日子可能不会那么快到来,我有个建议,是不是可以给在启用tcpmux的时候,可以设置yamux的stream最大缓冲大小。yamux默认的最大缓冲大小为256KB,这个缓冲比较保守。
这样当每个stream实际可用速度大于 256KB/RTT 的时候就至少受一个TTL时间的缓冲等待影响。

假设当前client和server的RTT为50ms,当速度要大于 256KB*(1000ms/50ms) = 5MB/s = 40Mb/s 时,就要等待一个RTT时间来确认缓冲区,这个传输时间的影响最大是多等待一个RTT,速度会降到 20Mb/s左右。那么在这种RTT稳定为50ms的情况下,即使CPU运算再快,带宽再大,速度也不可能提升,而相应的提高这个最大缓存带入公式可以得到相应的速度提升(这个速度是指每个stream的最大速度)。

这个缓冲区设置可以针对实际的网络使用情况进行优化。例如,如果网络传输为常规的网页访问,小的请求头,比较大的下行,那么只需要提高Client这一端的缓存,反之也是如此。当这个缓存提高到10MB这个RTT影响会比较小了,甚至当网络传输不大于5MB的时候不会受到这个RTT的影响。

再来说这个缓冲调大后带来的问题,假如Client端的缓存调整为10MB,只要Client端读取没有出现阻塞,一个stream所占用的内存也并不会大到10MB。所以我觉得对处于安全网络环境的frp用户可以根据自己的需要调整这个大小,优化自己的网络。给用户一个选择的机会,也是一个用空间换时间的做法

@fatedier
Copy link
Owner

@aaftio 可以考虑,是否可以有相应的测试数据来说明其影响?

@hayden-pan
Copy link

@aaftio 可以考虑,是否可以有相应的测试数据来说明其影响?

可以,但是大带宽环境我只有局域网环境,并且由于延迟只有5ms左右,应该只有很大的数据包传输才能看到效果,等我试试

@fatedier
Copy link
Owner

fatedier commented Aug 26, 2022

@aaftio 可以考虑,是否可以有相应的测试数据来说明其影响?

可以,但是大带宽环境我只有局域网环境,并且由于延迟只有5ms左右,应该只有很大的数据包传输才能看到效果,等我试试

linux 下可以使用 tc 模拟丢包和延迟,可以直接在单机环境测试。

@romotc
Copy link

romotc commented Oct 16, 2022

smux

方便把替换成smux之后的代码开源一下吗?

@Triangleowl
Copy link

通过调大yamux.Config.MaxStreamWindowSize(默认大小为256*1024,不能低于此值)可以缓解限速问题。如果带宽比较大的情况下,使用yamux做多路复用,假设多路复用客户端和服务端的RTT t ms,则单个stream的带宽约为:
((1000/t) * (MaxStreamWindowSize/2) * 8)/(1024*1024) Mbps

@hayden-pan
Copy link

@aaftio 可以考虑,是否可以有相应的测试数据来说明其影响?

可以,但是大带宽环境我只有局域网环境,并且由于延迟只有5ms左右,应该只有很大的数据包传输才能看到效果,等我试试

linux 下可以使用 tc 模拟丢包和延迟,可以直接在单机环境测试。

近段工作生活变化很大,没有花时间在这上面了,所以鸽了,只能等有时间了再折腾这块

@hayden-pan
Copy link

通过调大yamux.Config.MaxStreamWindowSize(默认大小为256*1024,不能低于此值)可以缓解限速问题。如果带宽比较大的情况下,使用yamux做多路复用,假设多路复用客户端和服务端的RTT t ms,则单个stream的带宽约为: ((1000/t) * (MaxStreamWindowSize/2) * 8)/(1024*1024) Mbps

如之前的交流,是想以测试结果来验证理论,如果方便有时间你可以帮忙发个测试结果么。

@Triangleowl
Copy link

image
这个是我使用yamux做代理测试的结果(自己写的一个简单的多路复用代理,没有用frp)。从实验结果来看,通过调大yamux.Config.MaxStreamWindowSize可以缓解带宽限制,这个限制只针对_单个stream_。比如带宽的物理限制是100Mbps,使用了多路复用后单个stream被限制到10Mbps,则开启两个stream时,两个stream都能达到10Mbps。

@hayden-pan
Copy link

image 这个是我使用yamux做代理测试的结果(自己写的一个简单的多路复用代理,没有用frp)。从实验结果来看,通过调大yamux.Config.MaxStreamWindowSize可以缓解带宽限制,这个限制只针对_单个stream_。比如带宽的物理限制是100Mbps,使用了多路复用后单个stream被限制到10Mbps,则开启两个stream时,两个stream都能达到10Mbps。

谢谢你的数据。 我刚刚才看到现在已经支持 QUIC 了!这个似乎已经不那么急了 。

@fatedier 这个测试虽然没有通过改变 RTT 来验证是 RTT 对传输速度上限的影响,但是验证了在相同的 RTT 下,不同的最大缓冲区对传输上限的影响。当然在提供这个参数设置的时候,为了更好去解释这个参数,还需要提供 Client 端的设置值和 Server 端的设置值对不同传输场景的影响。如果还是觉得添加这个配置的条件不足,再等等我有时间提供再详细的测试数据。

@fatedier
Copy link
Owner

fatedier commented May 8, 2023

@Triangleowl @aaftio 非常感谢你们提供的数据和对这方面的研究。

我自己对于 yamux 的各个参数细节可能没有精力深入,所以相对会比较谨慎。如果确实能解决问题,提供参数配置也没问题。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants