源码分析
在说run
方法之前,由于CliDriver
需要得到一个Driver
类的实例,所以首先看一下Driver
的构造方法。Driver
有三个构造函数,主要功能也就是设置类的实例变量HiveConf
。SessionState
前文已经有介绍,SessionState
返回了当前会话的一些信息,提取配置文件,初始化Driver
实例。
public Driver() {
if (SessionState.get() != null) {
conf = SessionState.get().getConf();
}
}
run
下面就开始解析Driver
内部对用户命令command
的处理流程,首先是入口函数run
. run
函数通过调用runInternal
方法处理用户指令,在处理完成runInternal
之后,如果执行过程中出现出错,还附加了对错误码和错误信息的处理,此处省略。
public CommandProcessorResponse run(String command)
throws CommandNeedRetryException {
return run(command, false);
}
public CommandProcessorResponse run(String command, boolean alreadyCompiled)
throws CommandNeedRetryException {
CommandProcessorResponse cpr = runInternal(command, alreadyCompiled);
...
}
runInternal
runInternal
方法包含的主要操作有,处理preRunHook
(具体功能可以顾名思义哦),compile
, execute
, 处理postRunHook
以及构造CommandProcessorResponse
并返回。下面依次从代码的角度分析这几步的具体操作:
PreRunHook
处理preRunHook
,首先根据配置文件和指令,构造用户Hook执行的上下文hookContext
,然后读取用户PreRunHook
配置指定的类(字符串), 此配置项对应于Hive配置文件当中的“hive.exec.driver.run.hooks”
一项,利用反射机制Class.forName
实例化PreRunHook
类实例(getHook
函数完成),依次执行各钩子的功能(preDriverRun
函数完成)。
HiveDriverRunHookContext hookContext
= new HiveDriverRunHookContextImpl(conf, command);
// Get all the driver run hooks and pre-execute them.
List<HiveDriverRunHook> driverRunHooks;
try{
driverRunHooks = getHooks(HiveConf.ConfVars.HIVE_DRIVER_RUN_HOOKS,
HiveDriverRunHook.class);
for (HiveDriverRunHook driverRunHook : driverRunHooks) {
driverRunHook.preDriverRun(hookContext);
}
}catch (Exception e) {
errorMessage = "FAILED: Hive Internal Error: " + Utilities.getNameMessage(e);
SQLState = ErrorMsg.findSQLState(e.getMessage());
downstreamError = e;
console.printError(errorMessage + "\n"
+ org.apache.hadoop.util.StringUtils.stringifyException(e));
return createProcessorResponse(12);
}
compile
编译,直接调用complieInternal
函数编译用户指令,将指令翻译成MapReduce
任务。
execute
在运行之前还有获取锁的操作,由于新版本添加了ACID
事务的支持,还设置了事务管理器等,目前还没详细的弄懂这块的处理逻辑和功能,先放一下,主要看下execute
函数执行了什么操作,也就是如何根据编译结果执行任务的。
首先是从编译得到的查询计划QueryPlan
里获取基本的查询ID,查询字串等信息,并在回话状态中把当前查询字串和查询计划插入到历史记录中。
String queryId = plan.getQueryId();
String queryStr &