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

bthread signal & wait 问题咨询 #2849

Open
MJY-HUST opened this issue Dec 13, 2024 · 9 comments
Open

bthread signal & wait 问题咨询 #2849

MJY-HUST opened this issue Dec 13, 2024 · 9 comments

Comments

@MJY-HUST
Copy link
Contributor

MJY-HUST commented Dec 13, 2024

image

在使用过程中,观察server侧的火焰图,此时brpc_worker thread的cpu基本打满。发现futex_wake、futex_wait占用的时间占比比较高,竞争锁成为了瓶颈。怀疑可能是由于调度不均衡,某些worker中的task较多,而一些worker的task较少,当这些task消费完之后每次都会调用wait,然后又快速被signal唤醒。同时也存在parking_lot中没有wait的线程但仍然在signal的场景。

这方面是否存在一些优化点,比如:

  1. signal时判断是否存在wait状态的线程;
  2. wait之前先尝试steal_task n 次,如果都失败再wait挂起线程;或者wait时设置timeout时间而不是每次都是永久wait,只能被signal主动唤醒。
@chenBright
Copy link
Contributor

Related issues: #2817
Related PR: #2819 #2398

@icexin
Copy link
Contributor

icexin commented Dec 17, 2024

这个是一个普遍问题,我们线上也遇到了。有状态服务一般会独占机器,现在机器普遍核数都比较多,基本都100+核数了。目前看到brpc在bthread worker比较多的时候调度开销比较大,希望社区能尽快解决一下哈~ ❤️

@yanglimingcn
Copy link
Contributor

@MJY-HUST
Copy link
Contributor Author

我看现在parking_lot的数量是写死的,一个tag内只有四个;一旦worker数量多了,futex中锁的竞争就上来了,想问一下这个值改成一个可配的参数或者根据tag所属的worker总数来动态调大会有什么负面影响吗?(比如parking_lot的数量 = bthread_concurrency_by_tag / 4 or 8)。
我自己做了一些测试,除了上述的做法之外,减少无效的signal和在wait前先steal一次也能解决一部分问题。
相同的负载:
启动四个rpc_press
./rpc_press -proto=echo_c++/echo.proto -method=example.EchoService.Echo -input='{"message":"hello"}' -qps=100000 -server=0.0.0.0:8000 -timeout_ms=-1
服务端使用example/echo_c++中的,server,worker线程数量为64个,但是在服务内增加了使用bthread_start_background创建两个bthread来模拟触发signal的行为,优化前后:
前:
image
image
image

后:parking_lot改为16个
image
image
image

@GreateCode
Copy link
Contributor

可以试试分组 https://github.com/apache/brpc/blob/master/docs/cn/bthread_tagged_task_group.md

分tag得把N个tag(brpc::Server)绑到N个port吧,不太优雅

@yanglimingcn
Copy link
Contributor

可以试试分组 https://github.com/apache/brpc/blob/master/docs/cn/bthread_tagged_task_group.md

分tag得把N个tag(brpc::Server)绑到N个port吧,不太优雅

是的,需要这么做,如果各个Server之间没有要求很强的隔离性,那确实也不用这么做。本质上是得优化协程调度。

@zhengJade
Copy link
Contributor

据我观察,频繁的触发 futex_wake 和 futex_wait 的原因是因为整个系统在“不必要”的时机进入的休眠状态,这样很容易产生一个 wake 和 多个 wait,导致系统调用频繁,worker 越多,wait 和 wake 越频繁,所以减少如何减少这种“不必要性”才是最重要的。我这边经过大量的测试发现一个 case 就是整个系统在高压繁忙下也进入了 wait 状态,很明显这是“不合适的”,“不必要的”。这是由于当前的模型下,会导致 epoll 延后处理,形成了多个 worker 工作在一个 queue 上,queue 没有了,立刻都进入休眠,然后 epoll 被唤醒后,“worker 们”又相继被唤醒,造成了”不必要性“。

@GreateCode
Copy link
Contributor

据我观察,频繁的触发 futex_wake 和 futex_wait 的原因是因为整个系统在“不必要”的时机进入的休眠状态,这样很容易产生一个 wake 和 多个 wait,导致系统调用频繁,worker 越多,wait 和 wake 越频繁,所以减少如何减少这种“不必要性”才是最重要的。我这边经过大量的测试发现一个 case 就是整个系统在高压繁忙下也进入了 wait 状态,很明显这是“不合适的”,“不必要的”。这是由于当前的模型下,会导致 epoll 延后处理,形成了多个 worker 工作在一个 queue 上,queue 没有了,立刻都进入休眠,然后 epoll 被唤醒后,“worker 们”又相继被唤醒,造成了”不必要性“。

你的PR #2819 先合下?

@zhengJade
Copy link
Contributor

据我观察,频繁的触发 futex_wake 和 futex_wait 的原因是因为整个系统在“不必要”的时机进入的休眠状态,这样很容易产生一个 wake 和 多个 wait,导致系统调用频繁,worker 越多,wait 和 wake 越频繁,所以减少如何减少这种“不必要性”才是最重要的。我这边经过大量的测试发现一个 case 就是整个系统在高压繁忙下也进入了 wait 状态,很明显这是“不合适的”,“不必要的”。这是由于当前的模型下,会导致 epoll 延后处理,形成了多个 worker 工作在一个 queue 上,queue 没有了,立刻都进入休眠,然后 epoll 被唤醒后,“worker 们”又相继被唤醒,造成了”不必要性“。

你的PR #2819 先合下?

好的,已经在修改中了,刚空出时间来搞

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

No branches or pull requests

6 participants