百万 Go TCP 连接的思考2: 百万连接的吞吐率和延迟
https://colobu.com/2019/02/27/1m-go-tcp-connection-2/
大佬可以再对比测试下,当不使用 workerpool,直接 go func() 所表现的吞吐率和延迟?
第三篇文章访问不了 是没写 还是删了?
@rfyiamcool 大佬可以再对比测试下,当不使用 workerpool,直接 go func() 所表现的吞吐率和延迟? 已加
多 epoller + worker pool 是不是会更好。
自己搞 epoller 跟用 runtime 的 netpoller 区别在哪呢
@choleraehyq 第一,自己搞的可以实现多 acceptor(高性能)。第二,可以用一个 goroutine 监听多个 conn(低消耗)。不过问题在于,自己搞的没了调度的优势,所以一旦后端耗时较长,会表现的更差,只能靠 worker pool 来实现调度。
@Laisky 对于长连接的场景,多个 acceptor 有多大优势? 所以我理解好处就是可以节省一些 goroutine 的内存开销?如果连接数没有高到百万这个级别的话,其实这个优势也不大明显
@choleraehyq
对于长连接的场景,多个 acceptor 有多大优势?
多 acceptor 的优势就在于高频的创建新连接(这也是当初 SO_REUSEPORT 的初衷)。
所以我理解好处就是可以节省一些 goroutine 的内存开销?
这确实是自己搞 epoller 的优势。和 worker pool 一起用好了还能实现低延迟。
如果连接数没有高到百万这个级别的话,其实这个优势也不大明显
我个人也是同感。绝大部分场景时使用 goroutine 方案应该会更好,19 GB 内存并不是不可接受。至于延迟,worker pool 方案的 pool size 也会很难设置。
@Laisky 长连接的场景一般是不会高频的创建新链接的。
另外,为什么自己搞 epoller + worker pool 能实现更低的延迟呢?跟 netpoller + worker pool 相比有什么差别
@choleraehyq netpoller + worker pool,每一个 worker 对应的是一个 conn。而自己搞 epoller + worker pool,每一个 worker 对应的是一个已唤醒的 conn。所以后者的 goroutine 数量会显著的低于前者,对应更低的调度开销(当然,还是取决于具体参数,比如前者你也可以设置一个很小的 pool size,但是这样延迟反而会更高)。
你好请教一下,这里最后的测试对比中,多epoller跟prefork方式都是总共50个epoller,区别是前者50用50个goroutine处理50个epoller,后者用50个进程处理50个epoller。结果是延时增加1倍,这个我的理解是cpu在进程间切换消耗比在goroutine间切换消耗大,那么既然切换消耗更大,又是用什么换得吞吐量增加1倍呢?我的理解是既然cpu在进程间切换消耗更大,在单位时间内能处理的任务只会更少,应该链接延时增大的同时吞吐量减少才对。
求教!
想问下吞吐率和延迟统计的代码或者脚本在这里面吗?
acceptor只负责负载均衡把链接分给epoller,我认为这个地方不需要开多协程,应该把侧重点放在处理网络数据缓存区这里吧
@Laisky 多 epoller + worker pool 是不是会更好。
本来是这么做的吧,epoller复制链接读写,worker-pool处理业务逻辑。
prefork 和 server 多epoller,感觉吞吐不应该差那么多, 是不是多epoller设定的epoller个数与prefork进程数差的有点多?
@Laisky @choleraehyq netpoller + worker pool,每一个 worker 对应的是一个 conn。而自己搞 epoller + worker pool,每一个 worker 对应的是一个已唤醒的 conn。所以后者的 goroutine 数量会显著的低于前者,对应更低的调度开销(当然,还是取决于具体参数,比如前者你也可以设置一个很小的 pool size,但是这样延迟反而会更高)。
我有一个不解的问题,golang netpoller 底层(linux)采用的也是 epoller(net.Listen),为什么需要在 netpoller 再搞一层 epoller,netpoller + worker pool 本质上不就是 epoller + worker pool 吗?
update: 我懂了,之前对 netpoller 理解有误
有个问题,在worker pool模型中,io.CopyN(conn,conn,8)是不是存在阻塞风险,导致这个worker没法处理后续的任务;以至于在多个链接的情况下,几个存在网络阻塞的链接会影响其他好的链接?
你好,有个问题请教下:在prefork模式下和work pool模式下,吞吐量差别的原因是啥?操作系统进程调度优于GMP的协程调度?? 另外他们的吞吐量和时延都是在同样的CPU利用率下吗?
你好,有个问题请教下:在prefork模式下和work pool模式下,吞吐量差别的原因是啥?操作系统进程调度优于GMP的协程调度?? 另外他们的吞吐量和时延都是在同样的CPU利用率下吗?
有两个瓶颈,一个是 accept new connection,另一个是 established connection handler。
prefork/multi epoller 解决的是第一个瓶颈。work pool 解决的是第二个瓶颈。