之前应该粗略的看了Presto启动的流程,完成了的话控制台应该打印这句
io.prestosql.server.PrestoServer ======== SERVER STARTED ========
然后程序就一直阻塞着等待我们发起查询,下面便是提交简单的查询看看是如何处理的
java -jar presto-cli/target/presto-cli-316-executable.jar --server localhost:8080
打开Presto客户端,再select 1
拿到下图的结果
同时控制台也多了一行信息,根据这行信息不难猜出是io.prestosql.event.QueryMonitor
这个类处理的查询
- 先从整体上看一下这个类
来到这个类,发现这个类有一个构造函数,三个公开的方法,很多私有方法。
其中,最容易理解的是queryCompletedEvent()
,它获得查询的状态,并且调用logQueryTimeline()
输出了我们看到的这行日志信息。
- 再具体分析这些方法
私有方法是封装的一些过程在公开方法中被调用,我们切入口主要就是在公有方法,所以在queryCreatedEvent()
中加入断点。
这时再查询select 1
,程序跳到了我们断点的位置,并且从queryInfo中找到了我们查询的信息。同时也能知道是queryCreatedEvent()
调用了这个方法
进入queryCreatedEvent()
,能够看到query是通过参数传递过来的
接着深入,经过createQueryInternal()
和createQuery()
发现run()
方法进不去
注意这里会经过
DispatchManager
类,后面会再次提到
只能先跳到runWorker()
发现这个类是ThreadPoolExecutor
注意task在while循环中,那么可以猜测
QueryMonitor
的queryCreatedEvent()
和queryCompletedEvent()
都是作为task被调用。在task.run()中加入断点不难验证这个猜想,实际上调用的task比较多不再一一展示。
ThreadPoolExecutor
有一个内部类Worker
,在它的runWorker()
上加断点
再次发起查询,可以发现firstTask中的一个arg是select 1
,正是之后调用这个task的run()
方法才进入了我们上面看到的那些流程。
而这个firstTask的类型就是
DispatchManager
总结起来是waiting的线程中调用了DispatchManager
的createQueryInternal()
,层层深入到了QueryMonitor