文档章节

hive 命令行提交sql 执行过程

政委007
 政委007
发布于 2017/04/27 15:46
字数 1022
阅读 102
收藏 3

承接上一篇文档:hive cli 启动 本文继续说查看hive源码,分析hive sql 执行过程。但不会详细解析sql 编译过程,因为我也不懂,还没看到😭。

processLine方法

//line : 要执行的命令 。 allowInterrupting : 命令是否可以被中断
 public int processLine(String line, boolean allowInterrupting) {
        SignalHandler oldSignal = null;
        Signal interruptSignal = null;
        //判断是否允许任务终止
        if (allowInterrupting) {
            //定义接收到的信号 (可以用Ctrl+c ,和kill -2两种方式触发信号 )
            interruptSignal = new Signal("INT");
            oldSignal = Signal.handle(interruptSignal, new SignalHandler() {
                private final Thread cliThread = Thread.currentThread();
                private boolean interruptRequested;

                @Override
                public void handle(Signal signal) {
                    boolean initialRequest = !interruptRequested;
                    interruptRequested = true;

                    // Kill the VM on second ctrl+c 当按两次Ctrl+ c时 退出jvm
                    if (!initialRequest) {
                        console.printInfo("Exiting the JVM");
                        System.exit(127);
                    }

                    // Interrupt the CLI thread to stop the current statement and return
                    // to prompt
                    console.printInfo("Interrupting... Be patient, this might take some time.");
                    console.printInfo("Press Ctrl+C again to kill JVM");

                    // First, kill any running MR jobs 杀死所有正在运行的任务,HadoopJobExecHelper 这个类中保存了正在运行的hadoop job ,任务会在这个类的progress()方法中循环获取执行进度,并且保存了所有这个jvm 中执行的任务。
                    HadoopJobExecHelper.killRunningJobs();
                    TezJobExecHelper.killRunningJobs();
                    HiveInterruptUtils.interrupt();
                }
            });
        }

        try {
            int lastRet = 0, ret = 0;

            String command = "";
            for (String oneCmd : line.split(";")) {

                if (StringUtils.endsWith(oneCmd, "\\")) {
                    command += StringUtils.chop(oneCmd) + ";";
                    continue;
                } else {
                    command += oneCmd;
                }
                if (StringUtils.isBlank(command)) {
                    continue;
                }
                //执行命令,根据命令不同做出不同对应,包括对退出,执行sql文件,执行linux命令,和sql等命令处理
                ret = processCmd(command);
                //清理cli查询状态,包括需要查询的sql ,
                SessionState ss = SessionState.get();
                ss.setCommandType(null);
                command = "";
                lastRet = ret;
                boolean ignoreErrors = HiveConf.getBoolVar(conf, HiveConf.ConfVars.CLIIGNOREERRORS);
                if (ret != 0 && !ignoreErrors) {
                    CommandProcessorFactory.clean((HiveConf) conf);
                    return ret;
                }
            }
            CommandProcessorFactory.clean((HiveConf) conf);
            return lastRet;
        } finally {
            // Once we are done processing the line, restore the old handler
            if (oldSignal != null && interruptSignal != null) {
                Signal.handle(interruptSignal, oldSignal);
            }
        }

processCmd() 方法

public int processCmd(String cmd) {
        CliSessionState ss = (CliSessionState) SessionState.get();
        ss.setLastCommand(cmd);
        conf.set(HiveConf.ConfVars.HIVEQUERYID.varname, QueryPlan.makeQueryId());
        // Flush the print stream, so it doesn't include output from the last command
        ss.err.flush();
        String cmd_trimmed = cmd.trim();
        //按空格分隔命令
        String[] tokens = tokenizeCmd(cmd_trimmed);
        int ret = 0;
        //  quit或exit: 关闭回话,退出hive
        if (cmd_trimmed.toLowerCase().equals("quit") || cmd_trimmed.toLowerCase().equals("exit")) {
            ss.close();
            System.exit(0);
            // 文件处理
        } else if (tokens[0].equalsIgnoreCase("source")) {
           
            //! 开头: 调用Linux系统的shell执行指令
        } else if (cmd_trimmed.startsWith("!")) {
        }  else { // local mode 本地模式:创建CommandProcessor, 执行用户指令
            try {
                //根据命令的第一个词语判断是set,reset,dfs,add,list,delete,reload,crypto等返回不同的命令处理器,其他返回一个Driver类
                CommandProcessor proc = CommandProcessorFactory.get(tokens, (HiveConf) conf);
                //处理sql
                ret = processLocalCmd(cmd, proc, ss);
            } catch (SQLException e) {
                console.printError("Failed processing command " + tokens[0] + " " + e.getLocalizedMessage(),
                        org.apache.hadoop.util.StringUtils.stringifyException(e));
                ret = 1;
            }
        }

        return ret;
    }

processLocalCmd方法

作用: 处理sql命令,根据不同的命令处理器处理不同sql命令,主要区分处理器是否是Driver类,如果是,处理除了(set,reset,dfs,add,list,delete,reload,crypto)命令外的其他sql ,如果不是调用各自处理器的run方法

 int processLocalCmd(String cmd, CommandProcessor proc, CliSessionState ss) {
        int tryCount = 0;
        boolean needRetry;
        int ret = 0;
        //执行命令时如果抛出CommondNeedRetryException 异常 命令会被重复执行
        do {
            try {
                needRetry = false;
                if (proc != null) {
                    // //如果CommandProcessor是Driver实例
                    if (proc instanceof Driver) {
                        Driver qp = (Driver) proc;
                        //获取标准输出流,打印结果信息
                        PrintStream out = ss.out;
                        long start = System.currentTimeMillis();
                        //回显命令
                        if (ss.getIsVerbose()) {
                            out.println(cmd);
                        }
                        //能获取运行的命令,获取不到history的日志文件
                        qp.setTryCount(tryCount);
                        //driver实例运行用户指令,获取运行结果响应码
                        ret = qp.run(cmd).getResponseCode();
                        //如果执行失败,直接返回
                        if (ret != 0) {
                            qp.close();
                            return ret;
                        }
                        //// 统计指令的运行时间
                        // query has run capture the time
                        long end = System.currentTimeMillis();
                        double timeTaken = (end - start) / 1000.0;

                        ArrayList<String> res = new ArrayList<String>();
                        //打印查询结果的列名称
                        printHeader(qp, out);
                        // 打印查询结果
                        // print the results
                        int counter = 0;
                        try {
                            if (out instanceof FetchConverter) {
                                ((FetchConverter)out).fetchStarted();
                            }
                            while (qp.getResults(res)) {
                                for (String r : res) {
                                    out.println(r);
                                }
                                counter += res.size();
                                res.clear();
                                if (out.checkError()) {
                                    break;
                                }
                            }
                        } catch (IOException e) {
                            console.printError("Failed with exception " + e.getClass().getName() + ":"
                                    + e.getMessage(), "\n"
                                    + org.apache.hadoop.util.StringUtils.stringifyException(e));
                            ret = 1;
                        }

                        int cret = qp.close();
                        if (ret == 0) {
                            ret = cret;
                        }

                        if (out instanceof FetchConverter) {
                            ((FetchConverter)out).fetchFinished();
                        }

                        console.printInfo("Time taken: " + timeTaken + " seconds" +
                                (counter == 0 ? "" : ", Fetched: " + counter + " row(s)"));
                    } else {
                        //如果proc不是Driver,也就是用户执行的是非SQL查询操作,直接执行语句,
                        String firstToken = tokenizeCmd(cmd.trim())[0];
                        String cmd_1 = getFirstCmd(cmd.trim(), firstToken.length());

                        if (ss.getIsVerbose()) {
                            ss.out.println(firstToken + " " + cmd_1);
                        }
                        //非查询操作,执行执行sql
                        CommandProcessorResponse res = proc.run(cmd_1);
                        if (res.getResponseCode() != 0) {
                            ss.out.println("Query returned non-zero code: " + res.getResponseCode() +
                                    ", cause: " + res.getErrorMessage());
                        }
                        ret = res.getResponseCode();
                    }
                }
            } catch (CommandNeedRetryException e) {
                console.printInfo("Retry query with a different approach...");
                tryCount++;
                needRetry = true;
            }
        } while (needRetry);

        return ret;
    }

© 著作权归作者所有

下一篇: hive cli启动
政委007
粉丝 10
博文 15
码字总数 15843
作品 0
洛阳
程序员
私信 提问
Hadoop(5)--hive

在Hadoop的存储处理方面提供了两种不同的机制,一种是之前介绍过的Hbase,另外一种就是Hive,有关于Hbase,它是一种nosql数据库的一种,是一种数据库,基于分布式的列式存储,适合海量数据的...

spark009
2018/08/14
0
0
Hive代码组织及架构简单介绍

hive三个主要组件 Serialzers/Deserialzers(trunk/serde) 此组件允许用户自己开发自定义序列化、反序列化文件解析器,hive自身也内置了一些序列化解析类。 MetaStore(trunk/metastore) 此组件...

扫大街的程序员
2013/11/03
2.9K
0
spark-submit.sh spark-shell.sh spark-sql.sh thrift

spark-submit.sh 提交spark任务 spark-shell.sh spark的交互命令窗口,底层其实还是使用spark-submit.sh提交了一个任务,但是driver programing可以和外界交互。spark-shell中已经实例化了s...

cjun1990
2016/04/12
57
0
Presto架构及原理、安装及部署

Presto 是 Facebook 推出的一个基于Java开发的大数据分布式 SQL 查询引擎,可对从数 G 到数 P 的大数据进行交互式的查询,查询的速度达到商业数据仓库的级别,据称该引擎的性能是 Hive 的 10...

hblt-j
01/27
220
1
Hive存储过程HQL/SQL(一)–hplsql命令行

PL/HQL主要是通过命令行工具来执行一个SQL查询语句或者是一个SQL脚本。 进入hplsql-0.3.11,执行./ hplsql即可显示命令行的用法: [liuxiaowen@dev hplsql-0.3.11]$ ./hplsql usage: hplsql...

Zero零_度
2016/07/07
848
0

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
10
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
8
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
11
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部