# Doris PipeLine后续的工作讨论
## 1.背景
当前Doris的执行引擎是volcano 的 pull 模型,在单机多核的场景下存在下面的一些问题:
* 无法利用多核计算能力,提升查询性能,**多数场景下进行性能调优时需要手动设置并行度**,在生产环境中几乎很难进行设定
* 阻塞算子依赖操作系统的线程调度机制,**线程切换开销大(尤其在系统混布的场景中)**
* CPU的资源管理困难,**很难做到更细粒度的资源管理,多查询的混合并发与并行的任务调度**
举些栗子:
* Tpch的SQL查询上,需要进行手动并发度的设置,否则默认单并发进行查询
* 默认配置,压力大时,大量的线程执行会打满单进程的线程上限
## 2.How To Do
### 2.1 需要解决的核心问题
#### 阻塞操作的异步化
阻塞算子会带来两个问题:
* **线程切换** :带来额外的上下文切换开销
* **线程占用** :阻塞的线程也会挤占单进程的线程资源
###### 阻塞操作
* I/O : 包含磁盘I/O与网络I/O
* Sort, HashJoinBuild,Agg等需要全量物化的算子
#### CPU的资源管理
混合负载场景中,出现CPU争夺的情况。CPU密集的大查询长时间挤占CPU资源,小查询得到CPU调度困难
### 2.2 可选的一些解决方案
###### 协程
协程能够自动将阻塞操作给异步化了:被阻塞的协程自动挂起,等待被唤醒,物理线程则调度执行下个可运行的协程。
但是这里注意:
* 1. 协程依赖协程本身的调度框架,对于混合负载的场景,无法进行更为合理的调度 (可能)
* 2. 操作系统陷入阻塞的操作可能导致死锁
* 3. Debug难度增加,逻辑死锁较难处理
###### Doris上的核心改动点:
* I/O部分和协程拆解,涉及:ScanNode / Exchange Node
* 全量物化算子的并行化,涉及:AggNode,HashJoinNode,SortNode
逻辑与多机分区类似(可参考Starrocks的**LocalExchange**实现)
* 同步原语的改写
* 手动出让CPU,模拟时间片的逻辑
![image.png](https://upload-images.jianshu.io/upload_images/8552201-31d35416bd29d3f2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
FE不感知BE端的任何协程拆解的工作,只通过Session Variable进行并发度设置即可。
这样我们可以保留 pull 模型,继续使用同步代码,但不需要担心阻塞问题。
###### Push模型重构
这块基本设计实现可以完全参照Starrocks和DuckDB,主要就是下面三个核心的部分:
* PipelineDriverExecutor, PipelineDriverPoller 设计实现Pipeline的调度队列,轮询规则,优先级
![image.png](https://upload-images.jianshu.io/upload_images/8552201-da9fdf51181a8464.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* PipelineBuilder 做pipeline的算子的构建,这里基本上需要重构一遍执行引擎
![image.png](https://upload-images.jianshu.io/upload_images/8552201-c512ed3abbc08e35.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* Pipeline 拆分,FE不感知pipeline的执行,所以这里需要将fragment翻译到pipeline
![image.png](https://upload-images.jianshu.io/upload_images/8552201-494b5c3022e296d3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
其他:
资源调度的工作:
* Starrocks实现WorkResource的来进行CPU的资源分配
* Pipeline实现了优先级队列
### 2.3 小结
| 开发方式 | 优点 | 缺点 | 参考实现 |
| :--------------------: | :------------------------: | :--------------------------: | :-------------------------------------------------------: |
| pull模型,基于协程重构 | 代码改动小,可快速验证上线 | 可定制性差,依赖协程库的实现 | TiFash(夭折实现,依赖Fiber库), MatrixOne(依赖Go协程实现) |
| push模型,重构执行引擎 | 可定制性强 | 代码改动量巨大 | DuckDB, Starrocks,ClickHouse |
## 3.工作推进
原则:**小步快跑,局部验证**.
poc先行,验证效果之后。目标流程和向量化开发一致:**单机->大宽表->多表join**
## 4.参考资料
* https://zhuanlan.zhihu.com/p/500254430
* https://zhuanlan.zhihu.com/p/575526096
* https://zhuanlan.zhihu.com/p/573181686
* https://zhuanlan.zhihu.com/p/528514990