先看0.7.1的执行过程:
hive> select * from table02 where id=500000;对于这样的一个查询,Hive从CliDriver这个类的main函数开始:
CliDriver.main(String[] args) CliSessionState ss=new CliSessionState(new HiveConf(SessionState.class)); SessionState.start(ss); CliDriver cli=new CliDriver(); 废话不多说来到了主要的循环: while((line=reader.readLine(curPrompt +"> "))!=null){ 处理每一行数据,当然还包括一些一个命令分成多行的处理,不多说。 ret=cli.processLine(line String); processCmd(oneLine);//可能一个line包含多个“;”,需要分开处理 一些特别的命令单独处理,像exit,source等。。。 CommandProcessor proc = CommandProcessorFactory.get(tokens[0],(HiveConf)conf); 这里set dfs add delete 会返回相应的处理器,其余的返回new Driver() if proc instance of Driver ret=proc.run(cmd).getResponseCode(); Driver.compile(cmd); Driver.execute(); 轮询compile出来的每一个task,Driver.launchTask(tsk,queryId,noName,running,jobname,jobs.ctx); 用TaskRunner包装tsk,tskRun.runSequential(); tsk.executeTask(); tsk.execute(drivercontext);调用相应的子类的execute方法。{ 举两个例子, 如果是show tables; 则是DDLTask,一直判断到ShowTableDesc showTbls= work.getShowTblsDesc(); if(showTbls !=null) return showTables(db,showTbls); 如果是上面那个查询;则是MapreduceTask,最后会来到这么一句话: executor=Runtime.getRuntime().exec(cmdLine,env,new File(workDir));//workDir是/home/allen/Desktop/hive-0.7.1 将executor所在进程的输出打印转移到本线程中来。 int exitVal=executor.waitFor(); //等待执行。 至于cmdLine是什么样,见前一篇文章。 返回retValue; } 返回retValue; 返回retValue; 从tskRun返回 从Driver.execute()返回成功值 return new CommandProcessResponse(retValue); 从proc.getResults(res) 打印query 结果 计算时间,打印出来 else 执行命令,set dfs等 return retValue; CommandProcessorFactory.clean() 返回返回值 终于回到了while循环体内。 } main函数体。
Driver.compile(cmd); 就是根据hql语句做优化,生成plan.xml的地方。以后要重点分析下。
现在看下0.8.1有什么改变
CliDriver.main(String[] args){
int ret=run(args);// while循环没有放到main函数里面,为什么要这样
System.exit(ret);
}
看run(args){ CliSessionState ss =new CliSessionState(new HiveConf(SessionState.class));//上来这里就报找不到bulltin class{ 调用了CliSessionState(hiveconf)构造函数{ super(conf);//super就是SessionState{ Class<?> pluginClass =Utilities.getBuiltinUtilsClass(); Url jarLocation=pluginClass.getProtectionDomain().getCodeSource().getLocation(); 这里返回的是/hive-0.8.1/eclipse-out/ add_buildin_resource(ResourceType.JAR,jarLocation.toString()); FunctionRegistry.registerFunctionsFromPluginJar(jarLocation,pluginClass.getClassLoader()); //这里报异常,解决方法:将src/builtins/ 从build path 的src中删除,搞定!!! } } } SessionState.start(ss); CliDriver cli = new CliDriver(); while(读取命令行){ ret=cli.processLine(line,true); for(";"分割){ ret = processCmd(command);{ CommandProcessor proc = CommandProcessorFactory.get(token[0],conf); ret = processLocalCmd(cmd,proc,ss);{ 还是判断是否instanceof Driver{ 计时; ret= qp.run(command).getResponseCode();{ int ret = compile (command);{//这里报空指针,Debug了半天,是0.7.1生成的metastore直接给0.8.1用不支持的缘故 ParseDriver pd = new ParseDriver(); ASTNode tree =pd.parse(command,ctx); } ret=execute();{//Driver.execute() 对每一个tasks,launchTask(tsk,queryId,noName,running,jobname,jobs,driverCxt); 下面和0.7.1一样。。。 } } } } } } } }