gitalk icon indicating copy to clipboard operation
gitalk copied to clipboard

百万 Go TCP 连接的思考2: 百万连接的吞吐率和延迟

Open smallnest opened this issue 6 years ago • 19 comments

https://colobu.com/2019/02/27/1m-go-tcp-connection-2/

smallnest avatar Feb 27 '19 10:02 smallnest

大佬可以再对比测试下,当不使用 workerpool,直接 go func() 所表现的吞吐率和延迟?

rfyiamcool avatar Feb 28 '19 04:02 rfyiamcool

第三篇文章访问不了 是没写 还是删了?

zhbinary avatar Mar 01 '19 06:03 zhbinary

@rfyiamcool 大佬可以再对比测试下,当不使用 workerpool,直接 go func() 所表现的吞吐率和延迟? 已加

smallnest avatar Mar 01 '19 08:03 smallnest

多 epoller + worker pool 是不是会更好。

Laisky avatar Mar 07 '19 09:03 Laisky

自己搞 epoller 跟用 runtime 的 netpoller 区别在哪呢

choleraehyq avatar Mar 08 '19 14:03 choleraehyq

@choleraehyq 第一,自己搞的可以实现多 acceptor(高性能)。第二,可以用一个 goroutine 监听多个 conn(低消耗)。不过问题在于,自己搞的没了调度的优势,所以一旦后端耗时较长,会表现的更差,只能靠 worker pool 来实现调度。

Laisky avatar Mar 11 '19 03:03 Laisky

@Laisky 对于长连接的场景,多个 acceptor 有多大优势? 所以我理解好处就是可以节省一些 goroutine 的内存开销?如果连接数没有高到百万这个级别的话,其实这个优势也不大明显

choleraehyq avatar Mar 11 '19 03:03 choleraehyq

@choleraehyq

对于长连接的场景,多个 acceptor 有多大优势?

多 acceptor 的优势就在于高频的创建新连接(这也是当初 SO_REUSEPORT 的初衷)。

所以我理解好处就是可以节省一些 goroutine 的内存开销?

这确实是自己搞 epoller 的优势。和 worker pool 一起用好了还能实现低延迟。

如果连接数没有高到百万这个级别的话,其实这个优势也不大明显

我个人也是同感。绝大部分场景时使用 goroutine 方案应该会更好,19 GB 内存并不是不可接受。至于延迟,worker pool 方案的 pool size 也会很难设置。

Laisky avatar Mar 11 '19 05:03 Laisky

@Laisky 长连接的场景一般是不会高频的创建新链接的。

另外,为什么自己搞 epoller + worker pool 能实现更低的延迟呢?跟 netpoller + worker pool 相比有什么差别

choleraehyq avatar Mar 11 '19 06:03 choleraehyq

@choleraehyq netpoller + worker pool,每一个 worker 对应的是一个 conn。而自己搞 epoller + worker pool,每一个 worker 对应的是一个已唤醒的 conn。所以后者的 goroutine 数量会显著的低于前者,对应更低的调度开销(当然,还是取决于具体参数,比如前者你也可以设置一个很小的 pool size,但是这样延迟反而会更高)。

Laisky avatar Mar 11 '19 07:03 Laisky

你好请教一下,这里最后的测试对比中,多epoller跟prefork方式都是总共50个epoller,区别是前者50用50个goroutine处理50个epoller,后者用50个进程处理50个epoller。结果是延时增加1倍,这个我的理解是cpu在进程间切换消耗比在goroutine间切换消耗大,那么既然切换消耗更大,又是用什么换得吞吐量增加1倍呢?我的理解是既然cpu在进程间切换消耗更大,在单位时间内能处理的任务只会更少,应该链接延时增大的同时吞吐量减少才对。

求教!

falconray0704 avatar Apr 06 '19 13:04 falconray0704

想问下吞吐率和延迟统计的代码或者脚本在这里面吗?

jackru88888 avatar Oct 14 '19 12:10 jackru88888

acceptor只负责负载均衡把链接分给epoller,我认为这个地方不需要开多协程,应该把侧重点放在处理网络数据缓存区这里吧

sugtex avatar Apr 11 '20 09:04 sugtex

@Laisky 多 epoller + worker pool 是不是会更好。

本来是这么做的吧,epoller复制链接读写,worker-pool处理业务逻辑。

sugtex avatar Apr 11 '20 09:04 sugtex

prefork 和 server 多epoller,感觉吞吐不应该差那么多, 是不是多epoller设定的epoller个数与prefork进程数差的有点多?

logicdevlogic avatar May 13 '20 12:05 logicdevlogic

@Laisky @choleraehyq netpoller + worker pool,每一个 worker 对应的是一个 conn。而自己搞 epoller + worker pool,每一个 worker 对应的是一个已唤醒的 conn。所以后者的 goroutine 数量会显著的低于前者,对应更低的调度开销(当然,还是取决于具体参数,比如前者你也可以设置一个很小的 pool size,但是这样延迟反而会更高)。

我有一个不解的问题,golang netpoller 底层(linux)采用的也是 epollernet.Listen),为什么需要在 netpoller 再搞一层 epollernetpoller + worker pool 本质上不就是 epoller + worker pool 吗?

update: 我懂了,之前对 netpoller 理解有误

happyxhw avatar Jan 30 '21 03:01 happyxhw

有个问题,在worker pool模型中,io.CopyN(conn,conn,8)是不是存在阻塞风险,导致这个worker没法处理后续的任务;以至于在多个链接的情况下,几个存在网络阻塞的链接会影响其他好的链接?

mikehb avatar Oct 09 '22 05:10 mikehb

你好,有个问题请教下:在prefork模式下和work pool模式下,吞吐量差别的原因是啥?操作系统进程调度优于GMP的协程调度?? 另外他们的吞吐量和时延都是在同样的CPU利用率下吗?

soach avatar Apr 03 '24 07:04 soach

你好,有个问题请教下:在prefork模式下和work pool模式下,吞吐量差别的原因是啥?操作系统进程调度优于GMP的协程调度?? 另外他们的吞吐量和时延都是在同样的CPU利用率下吗?

有两个瓶颈,一个是 accept new connection,另一个是 established connection handler。

prefork/multi epoller 解决的是第一个瓶颈。work pool 解决的是第二个瓶颈。

Laisky avatar Apr 03 '24 11:04 Laisky