Local resume task queue per task group.#2398
Conversation
…ched(),ready_to_run_remote() of TaskGroup
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Add resume_rq for remote task and improve wait_task.
* add no_signal parameter to notify_one * define guard for bthread_cond_signal
The latest code relies on: * C++11 -> C++17 * Glog minimum version >= 0.6.0
|
Could you describe what functionality this PR has implemented and the general implementation approach?(可以描述一下这个PR实现了什么功能,以及大致的实现思路吗?) |
|
我理解这个 MR 主要是两方面的工作:
就是这个steal策略有 2 个维度,一个是负载,一个是吞吐导向还是响应导向。如果负载低就应该用全局数据结构,反之要 shard。如果吞吐导向就应该 batch 唤醒和派发,反之应该激进唤醒 waiter。我不觉得有啥办法能把这 4 点就满足了。 华为最近 OSDI 2023 有篇 https://www.usenix.org/conference/osdi23/presentation/wang-jiawei tldr,我觉得线上作为默认调度都差点意思。BWoS 给 tokio 的 PR 好久还没合进去。 |
|
@wwbmmm 这个是我们对 brpc 做的一些改动,提给我们的 fork 的,不小心提到了这里,sorry。正好趁这个机会大家讨论一下,已补充上下文。 |
1477516 to
14bcfab
Compare
这个是比较通用的一个优化,代码改动也比较小,可以单独提个PR吗?
这个需求感觉有点定制化。有测过这个改之后的实际性能收益吗? |
de2ac82 to
f9ce7cd
Compare
f9ce7cd to
d86060e
Compare
* change redis txn and support watch * update redis multi unit test
d86060e to
7e81e6e
Compare
@MrGuin 这个改动上线稳定运行了吗?可否推进一下合到社区。 |
好的,我抽空针对这个提个 PR。我们内部一直在用,目前还算稳定。c7g.16xlarge 机型下四五十个 worker 线程可以达到两三百万的 qps,性能可以正常随着 worker 数 scale,不会雪崩了。 |
|
这个有计划合并进来嘛,暂时没有的话,我就自己写了 |
What problem does this PR solve?
一个要解决的问题是 brpc worker 线程多的时候,由于大量的 signal_task 导致的性能雪崩。我们观察到 bthread_concurrency 多了后大量的 cpu 都会花费在 TaskContro::signal_task 以及 ParkingLot::signal 上,更具体是 ParkingLot::_pending_signal 这个原子变量上。signal_task 是一个热点函数,在每次发生 bthread 切换,新的 bthread 创建,以及等待中的 bthread 恢复执行时都会被调用;而 brpc 当前的 signal_task 的实现比较粗糙,每次 signal_task 都无差别地遍历对 parkinglot 做 signal,_pending_signal 的自增成为巨大的热点,会占用整体超过一半的 cpu。

这是我们在64核机器上 bthread_concurrency 设置为48时的 cpu profiling:
就像代码注释里所说,
针对 worker 唤醒,做的改动就是记录在 parkinglot 上等待的 worker num,只有有 worker 等待时才 signal_task;另外就是 steal_task 时让 worker 在 wait 在 parking lot 之前 busy poll 一小段时间,不那么频繁地 wait。
另外一个改动就是对于重新唤醒的 task 的处理。我们的场景 RPC bthread 会等待我们的 service 处理然后被唤醒,现有的 butex_wake 实现中虽然 brpc 的 worker 线程会立即切换到被唤醒的 bthread,但非 worker pthread 调用 butex_wake 只会把被唤醒的 bthread 给放进优先级很低的 _remote_rq。我们认为被唤醒的应该优先被处理,所以每个 TaskGroup 引入了额外的 _resume_rq 来保存由外部 pthread 唤醒的 bthread,在 wait_task 中优先检查。
What is changed and the side effects?
Changed:
Side effects:
Performance effects(性能影响):
Breaking backward compatibility(向后兼容性):
Check List: