PrestoSQL(trinodb)源码分析 - 执行(下)

TaskExecutor

那么都准备好了,就要开始真正的执行了

初始化的时候

增加TaskRunner线程

 

  

TaskRunner

核心就是不断的从waitingSplits中获取split,然后process

 

到这会创建driver,

 

CreateDriver

 

先使用之前的operatorFactory,创建出Operator对象,然后创建Driver

这里看下,ExchangeOperator的例子

  

对于ScanFilterAndProjectOperator

 

需要封装成,WorkProcessorSourceOperatorAdapter

这里会生成sourceOperator,ScanFilterAndProjectOperator

这里pages是workProcessor,如果要获取page,需要调用process接口实际获取

 

processFor

调用driver的processFor

 

 

 

processInternal

核心就是数据在pipeline中move的过程,可以看出在pipeline中数据是以push的方式进行的,在pipeline之间是pull的方式

 

Current.getOutput

 

pages的定义,

 

 所以按照这个反向执行,直到SplitToPages,

 

process,

先是生成source,这里就是访问TPCH的链接,从这里可以get到cursor,这是要作为参数用于get数据的

然后调用processColumnSource,

 

 processColumnSource

返回一个processor,RecordCursorToPages,

 

RecordCursorToPages被调用时,process

这里就用到前面生成的cursorProcessor来获取数据

cursorProcessor是CodeGen动态生成的,

 

代码生成

在生成PhysicalOperation的同时,做代码生成,

 

Visit,不停的迭代source,直到Filter

 

调用到visitScanFilterAndProject,几个参数需要注意

sourceNode, 是TableScanNode

FilterExpression,代表过滤条件

outputSymbols,代表projects

 

 这里逻辑,将filter和project生成,RowExpression

 

分别通过Complier生成CursorProcessor和PageProcessor类

这两个应该是对等的,只会使用一个

 

 

对于PageProcessor

会把filter,project,CodeGen成class,传入PageProcessor

 

所有processor都是通过process来执行,

这个processor的功能,执行filter得到selectedPosition,然后生成新的processor

 

这个ProjectSelectedPositions,再被process

调用,ProcessBatchResult result = processBatch(batchSize);

逻辑就是对于filter后的结果,执行project,最终返回ProcessResult

 

所以可以看出,PageProcess的目的就是对于page进行filter和project的操作,由于这里的filter和project是CodeGen的,所以整个部分都需要codeGen出来

 

对于CursorProcessor,更彻底,整个class都是动态生成的

expressionCompiler.compileCursorProcessor

 

 

 

这里核心逻辑是产生method,

可以看到主要生成,3中method,核心就是process,其他的filter和projec都是在process中需要调用到的函数

 

Process,

 

 createProjectIfStatement,

 

 

Blocked

每个split执行时,如果上游数据不ready,会怎么处理?

在TaskExecutor.TaskRunner中,会根据返回的blocked来判断

 

那么这个blocked怎么来的呢?

在Driver.processInternal中,如果没有movedPage,即没有数据被处理

那么就会从operator中获取blocked

 

getBlockedFuture 

这里取名有问题,isBlocked,不应该得到一个future,应该是一个bool

 

实现isBlocked的operator都是可能会出现block case的,基本都是和IO相关,大部分operator是不会block的

比如对于,WorkProcessorSourceOperatorAdapter

 

这里的firstFinishedFuture的挺有意思,

如果一个driver中有多个blocked点,那么需要找到最先完成的,那我怎么知道谁先完成了?

答案是,不知道;所以这里用SettableFuture,对于每个blocked加上listener,这样完成的时候就会把自己set到result,从而返回。

 

posted on 2022-01-07 15:35  fxjwind  阅读(706)  评论(2编辑  收藏  举报