Skip to content

Commit

Permalink
save work
Browse files Browse the repository at this point in the history
Signed-off-by: xufei <[email protected]>
  • Loading branch information
windtalker committed Sep 12, 2024
1 parent 53cfcdf commit 8f489ed
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion tiflash/tiflash-mintso-scheduler.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ summary: 介绍 TiFlash MinTSO 调度器。
本文介绍 TiFlash MinTSO scheduler 的原理与实现。

## 背景

在 TiDB 中,对于 MPP query,TiDB 会将 query 拆成一个或多个 MPPTask,并将 MPPTask 发送给对应的 TiFlash 节点。而在 TiFlash 节点内部,对每个 MPPTask 进行编译与执行。在 TiFlash 使用 [pipeline 执行模型](/tiflash/tiflash-pipeline-model.md) 之前,对于每个 MPPTask,TiFlash 都需要使用若干个线程(具体线程数取决于 MPPTask 的复杂度以及 TiFlash 并发参数的设置)来执行。在高并发场景中,TiFlash 节点会同时接受到多个 MPPTask,如果 TiFlash 不对 MPPTask 的执行有所控制,则 TiFlash 需要向系统申请的线程数会随着 MPPTask 数量的增加而线性增加。过多的线程一方面会影响 TiFlash 的执行效率,另一方面操作系统本身支持的线程数也是有限的,当 TiFlash 申请的线程数超过操作系统的限制时,TiFlash 就会碰到无法申请线程的错误。

为了提升在高并发场景下 TiFlash 的处理能力,我们需要在 TiFlash 中引入一个 task 的 scheduler。
Expand All @@ -19,6 +20,7 @@ summary: 介绍 TiFlash MinTSO 调度器。
<img src="/media/tiflash/tiflash_mintso_v1.png" width=50%></img>

尽管上述调度策略能有效控制系统的线程数,但是 MPPTask 并不是一个最小的独立执行单元,不同 MPPTask 之间会有依赖关系:

```
mysql> explain select count(*) from t0 a join t0 b on a.id = b.id;
+--------------------------------------------+----------+--------------+---------------+----------------------------------------------------------+
Expand All @@ -38,11 +40,13 @@ mysql> explain select count(*) from t0 a join t0 b on a.id = b.id;
| └─TableFullScan_23 | 10000.00 | mpp[tiflash] | table:b | pushed down filter:empty, keep order:false, stats:pseudo |
+--------------------------------------------+----------+--------------+---------------+----------------------------------------------------------+
```

上面的 query 会在每个 TiFlash 节点中生成 2 个 MPPTask,其中 `ExchangeSender_21` 所在的 MPPTask 依赖于 `ExchangeSender_45` 所在的 MPPTask。假设这个 query 高并发的情况下,调度器调度了每个 query 中 `ExchangeSender_45` 所在的 MPPTask,则系统就会进入死锁的状态。

为了避免系统陷入死锁的状态,我们引入了两层 thread 的限制:
* threads_soft_limit
* threads_hard_limit

其中 soft limit 主要用来限制系统使用的线程数,但是对于特定的 MPPTask,为了避免死锁可以打破这个限制,而 hard limit 则是为了保护系统,一旦超过 hard limit,TiFlash 可以通过报错来避免系统陷入死锁状态。

利用 soft limit 来避免死锁的思想很简单,系统中存在一个特殊的 query,该 query 的所有 MPPTask 在调度时都可以突破 soft limit 的限制,这样只要系统的 thread 不超过 hard limit,系统中就必定存在一个 query 的所有 MPPTask 都可以正常执行,这样系统就不会出现死锁。
Expand All @@ -51,5 +55,4 @@ MinTSO Scheduler 的目标就是在控制系统线程数的同时,确保系统

<img src="/media/tiflash/tiflash_mintso_v2.png" width=50%></img>


通过引入 soft limit 与 hard limit,MinTSO 能保证系统线程数的同时有效地避免了系统死锁。不过对于高并发场景,可能会出现大部份 query 都只有部分 MPPTask 被调度的情况,对于只有部分 MPPTask 被调度的 query,它们实际上无法正常执行,从而导致系统执行效率低下。为了避免这种情况,我们给 MinTSO Scheduler 在 query 层面引入了一个限制,即 active_query_soft_limit,该限制的意思是系统最多只有 active_query_soft_limit 个 query 的 MPPTask 可以参与调度,对于其他的 query,其 MPPTask 不参与调度,只有等当前 query 结束之后,新的 query 才能参与调度。当然这个限制只是一个 soft limit,因为对于 MinTSO query 来说,其所有 MPPTask 在系统线程数不超过 hard limit 的时候都可以直接被调度。

0 comments on commit 8f489ed

Please sign in to comment.