Hive源码分析:CLI入口类

说明:

本文的源码分析基于hive-0.10.0-cdh4.3.0。

启动脚本

从shell脚本/usr/lib/hive/bin/ext/cli.sh可以看到hive cli的入口类为org.apache.hadoop.hive.cli.CliDriver

	cli () {
	  CLASS=org.apache.hadoop.hive.cli.CliDriver
	  execHiveCmd $CLASS "$@"
	}
	cli_help () {
	  CLASS=org.apache.hadoop.hive.cli.CliDriver
	  execHiveCmd $CLASS "--help"
	}

入口类

java中的类如果有main方法就能运行,故直接查找org.apache.hadoop.hive.cli.CliDriver中的main方法即可。

CliDriver类中的方法有:

main方法代码如下:

	public static void main(String[] args) throws Exception {
	    int ret = run(args);
	    System.exit(ret);
	}

阅读run函数可以看到,主要做了以下几件事情:

  • 读取main方法的参数
  • 重置默认的log4j配置并为hive重新初始化log4j,注意,在这里是读取hive-log4j.properties来初始化log4j。
  • 创建CliSessionState,并初始化in、out、info、error等stream流。CliSessionState是一次命令行操作的session会话,其继承了SessionState。
  • 重命令行参数中读取参数并设置到CliSessionState中。
  • 启动SessionState并连接到hive server
  • 如果cli是本地模式运行,则加载hive.aux.jars.path参数配置的jar包到classpath
  • 创建一个CliDriver对象,并设置当前选择的数据库。可以在命令行参数添加-database database来选择连接那个数据库,默认为default数据库。
  • 加载初始化文件.hiverc,该文件位于当前用户主目录下,读取该文件内容后,然后调用processFile方法处理文件内容。
  • 如果命令行中有-e参数,则运行指定的sql语句;如果有-f参数,则读取该文件内容并运行。注意:不能同时指定这两个参数。

	hive -e 'show tables'
	hive -f /root/hive.sql
  • 如果没有指定上面两个参数,则从当前用户主目录读取.hivehistory文件,如果不存在则创建。该文件保存了当前用户所有运行的hive命令。
  • 在while循环里不断读取控制台的输入内容,每次读取一行,如果行末有分号,则调用CliDriver的processLine方法运行读取到的内容。
  • 每次调用processLine方法时,都会创建SignalHandler用于捕捉用户的输入,当用户输入Ctrl+C时,会kill当前正在运行的任务以及kill掉当前进程。kill当前正在运行的job的代码如下.

	HadoopJobExecHelper.killRunningJobs();
  • 处理hive命令。

处理hive命令过程

如果输入的是quit或者exit,则程序退出。

如果命令开头是source,则会读取source 后面文件内容,然后执行该文件内容。通过这种方式,你可以在hive命令行模式运行一个文件中的hive命令。

如果命令开头是感叹号,执行操作系统命令(如!ls,列出当前目录的文件信息)。通过以下代码来运行:

	Process executor = Runtime.getRuntime().exec(shell_cmd);
	StreamPrinter outPrinter = new StreamPrinter(executor.getInputStream(), null, ss.out);
	StreamPrinter errPrinter = new StreamPrinter(executor.getErrorStream(), null, ss.err);

	outPrinter.start();
	errPrinter.start();

	ret = executor.waitFor();
	if (ret != 0) {
	  console.printError("Command failed with exit code = " + ret);
	}

shell_cmd的内容大概如下:

	shell_cmd = "/bin/bash -c \'" + shell_cmd + "\'"

如果命令开头是list,列出jar/file/archive

如果是远程模式运行命令行,则通过HiveClient来运行命令;否则,调用processLocalCmd方法运行本地命令。

以本地模式运行时,会通过CommandProcessorFactory工厂解析输入的语句来获得一个CommandProcessor,CommandProcessor接口的实现类见下图:

从上图可以看到指定的命令(set/dfs/add/delete/reset)交给指定的CommandProcessor处理,其余的(指hql语句)交给Driver类来处理。

故,org.apache.hadoop.hive.ql.Driver类是hql查询的起点,而run()方法会先后调用compile()和execute()两个函数来完成查询,所以一个command的查询分为compile和execute两个阶段。

总结

作为尝试,第一次使用思维导图分析代码逻辑,简单整理了一下CliDriver类的运行逻辑,如下图。以后还需要加强画图和表达能力。

时间: 2024-09-19 00:45:10

Hive源码分析:CLI入口类的相关文章

Hive源码分析:Driver类运行过程

说明: 本文的源码分析基于hive-0.12.0-cdh5.0.1. 概括 从<hive cli的入口类>中可以知道hive中处理hive命令的处理器一共有以下几种: (1)set SetProcessor,设置修改参数,设置到SessionState的HiveConf里. (2)dfs DfsProcessor,使用hadoop的FsShell运行hadoop的命令. (3)add AddResourceProcessor,添加到SessionState的resource_map里,运行提交

大数据之Oozie——源码分析(一)程序入口

工作中发现在oozie中使用sqoop与在shell中直接调度sqoop性能上有很大的差异.为了更深入的探索其中的缘由,开始了oozie的源码分析之路.今天第一天阅读源码,由于没有编译成功,不能运行测试用例,直接使用sublime肉眼阅读,还是挺费劲的. 虽然流程还不是顺畅,但是大体上的内容还算是了解了. 我这里使用的是oozie4.2的版本,之前稍微看过4.3版本的,源码上还是有一定的差异的. 看上面的图,大致理解oozie的过程是: oozie cli提交任务 oozie server创建一

远哥Amoeba源码分析之:核心类说明

同事喜欢叫我远哥,所以我把这个笔记称为远哥系列,今天有兴趣分析一下Amoeba的源码,并且在此记录一下,并且随时更新.   Amoeba目前一共有三个项目产品,分别是:   Amoeba for MySQL: 为MySQL提供了一种数据库代理的解决方案,可以实现多台MySQL之间的读写分离,具有负载均衡.高可用性.Query过滤.读写分离.可路由相关的query到目标数据库.可并发请求多台数据库合并结果. 在Amoeba上面你能够完成多数据源的高可用.负载均衡.数据切片的功能.   Amoeba

springboot源码分析6-springboot之PropertySource类初探

摘要:本小节重点梳理一下PropertySource类的相关结构以及职责,本文的学习前提是学习了springboot源码分析5-springboot之命令行参数以及原理一文. 在springboot源码分析5-springboot之命令行参数以及原理一文中,我们看到了实例化Source类的时候,会去先实例化其父类SimpleCommandLinePropertySource.SimpleCommandLinePropertySource类的构造函数中直接解析了命令行参数以及值,然后返回封装好的C

springboot源码分析3-springboot之banner类架构以及原理

继续上文的<<springboot源码分析2-springboot 之banner定制以及原理章节>>进行讲解,上一节我们详细详解了banner的三种输出模式.banner的输出模式设置.banner类的架构.SpringApplicationBannerPrinter类.ImageBanner以及TextBanner的处理方式.本小节我们来重点讲解一下各种banner处理类的相关实现逻辑以及设计意图和职责. 1.1 SpringBootBanner类 SpringBootBann

深入理解Spark:核心思想与源码分析

大数据技术丛书 深入理解Spark:核心思想与源码分析 耿嘉安 著 图书在版编目(CIP)数据 深入理解Spark:核心思想与源码分析/耿嘉安著. -北京:机械工业出版社,2015.12 (大数据技术丛书) ISBN 978-7-111-52234-8 I. 深- II.耿- III.数据处理软件 IV. TP274 中国版本图书馆CIP数据核字(2015)第280808号 深入理解Spark:核心思想与源码分析 出版发行:机械工业出版社(北京市西城区百万庄大街22号 邮政编码:100037)

JUnir源码分析(一)

一.引子 JUnit源码是我仔细阅读过的第一个开源项目源码.阅读高手写的代码能学到一些好的编程风格和实现思路,这是提高自己编程水平行之有效的方法,因此早就想看看这些赫赫有名的框架是怎么回事了.今天就拿最简单的JUnit下手,也算开始自己的源码分析之路.   JUnit作为最著名的单元测试框架,由两位业界有名人士协力完成,已经经历了多次版本升级(了解JUnit基础.JUnit实践).JUnit总体来说短小而精悍,有不少值得我们借鉴的经验在里面:但是也有一些不足存在,当然这对于任何程序来说都是难免的

Hive源码编译及阅读修改调试

下载编译 在git上下载合适的master分支,使用maven编译.执行编译的目的在于,确保过程中生成的代码(Thrift)已经生成,这样导入IDEA就不会出现有些类找不到的情况. 执行源码编译分发命令,进入源码根目录执行: mvn clean package -Phadoop-2 -DskipTests -Pdist  这里必须指定profile为hadoop-2来支持hadoop 2.x版本 1.后续更改完源码后,还需执行该命令来编译打包.源码更改后需评价其对Hive各模块的影响(改动代码多

MapReduce源码分析之LocatedFileStatusFetcher

        LocatedFileStatusFetcher是MapReduce中一个针对给定输入路径数组,使用配置的线程数目来获取数据块位置的实用类.它的主要作用就是利用多线程技术,每个线程对应一个任务,每个任务针对给定输入路径数组Path[],解析出文件状态列表队列BlockingQueue<List<FileStatus>>.其中,输入数据输入路径只不过是一个Path,而输出数据则是文件状态列表队列BlockingQueue<List<FileStatus&g