Presto源码分析-Client提交流程

准备

Presto有两大分支一个prestodb,另一个是prestosql。二者的区别找到了一篇文章,可以了解一下。
在这里插入图片描述
我选择的是prestodb,git clone https://github.com/prestodb/presto.git

我写博客时,最近的commitcba87b4f111983b5483ab2ecf580573ac0afa595,这次提交完善了Materialized Views,详细可见 https://github.com/prestosql/presto/commit/88116a4a3fda92f0caa725d9b1a83e9b22f7dcf4

直接对master代码进行分析了,找到presto-cli模块下的com.facebook.presto.cli.Presto

idea中双击shift快速搜索到

在这里插入图片描述

分析

打开后代码很少,主要是对console的操作:创建、判断是否需要展示帮助或者展示版本信息、然后到真正的run,正常返回为0否则为1。

package com.facebook.presto.cli;

import static io.airlift.airline.SingleCommand.singleCommand;

public final class Presto
{
    private Presto() {}

    public static void main(String[] args)
    {
        Console console = singleCommand(Console.class).parse(args);

        if (console.helpOption.showHelpIfRequested() ||
                console.versionOption.showVersionIfRequested()) {
            return;
        }

        System.exit(console.run() ? 0 : 1);
    }
}

console.run()方法也不难理解

  1. 先是做一些判断:是execute参数提交的?还是file提交的?并做相应的处理。
    在这里插入图片描述
  2. 如果客户端终止了,查询也随之终止。
 // abort any running query if the CLI is terminated
        AtomicBoolean exiting = new AtomicBoolean();
        ThreadInterruptor interruptor = new ThreadInterruptor();
        CountDownLatch exited = new CountDownLatch(1);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            exiting.set(true);
            interruptor.interrupt();
            awaitUninterruptibly(exited, EXIT_DELAY.toMillis(), MILLISECONDS);
        }));
  1. 将query传入并执行命令。
    在这里插入图片描述
    进入executeCommand,发现它将query拆分成一条一条的交给process(查看StatementSplitter发现是按逗号拆分)
 private static boolean executeCommand(QueryRunner queryRunner, String query, OutputFormat outputFormat, boolean ignoreErrors)
    {
        boolean success = true;
        StatementSplitter splitter = new StatementSplitter(query);
        for (Statement split : splitter.getCompleteStatements()) {
            if (!isEmptyStatement(split.statement())) {
                if (!process(queryRunner, split.statement(), outputFormat, () -> {}, false)) {
                    if (!ignoreErrors) {
                        return false;
                    }
                    success = false;
                }
            }
        }
        if (!isEmptyStatement(splitter.getPartialStatement())) {
            System.err.println("Non-terminated statement: " + splitter.getPartialStatement());
            return false;
        }
        return success;
    }

process调用queryRunner.startQuery(finalSql)
在这里插入图片描述
实际上是startQuery层次调用startInternalQuery
在这里插入图片描述
最终得到StatementClientV1

public final class StatementClientFactory
{
    private StatementClientFactory() {}

    public static StatementClient newStatementClient(OkHttpClient httpClient, ClientSession session, String query)
    {
        return new StatementClientV1(httpClient, session, query);
    }
}

在StatementClientV1的构造方法中构造查询请求
在这里插入图片描述
接着进入可以看到url的路径
在这里插入图片描述
不难定位到com/facebook/presto/server/protocol/QueuedStatementResource.java:161
在这里插入图片描述
在这里对请求做出了响应,完成整个提交的请求。
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44112790/article/details/110000867