Hive:sql转mr任务源码解析
- 当我们执行一条sql的时候,程序的执行入口其实是org.apache.hadoop.hive.cli.CliDriver这个类,那么这个类有一个主方法的内容是new CliDriver().run(args)
- 进入run()方法,可以看到刚开始就new OptionProcessor()(选项处理器,用来处理args参数的),其中有两个方法,process_stage1(args),这个是用来解析通过命令行输入的参数,例如临时生效的hive参数等等,要是传入参数不正确,那么直接返回报错,返回1。
- 再往后,是ss.in(),ss.out()定义输入输出流,还有信息和错误的打印,因为我们打开客户端后,需要写sql得到结果,所以这里是需要输入输出流的,若注册流错误,返回3
- 往下面是可以看到OptionProcessor()的另一个方法process_stage2(ss)的调用,不过这一次传的参数是ss,里面就有定义数据库等参数的解析,默认是default数据库。这一步传参错误,返回2。
- 往下是用HiveConf()对参数进行一个封装,封装成key,value
- 再往后conf.getVar(HiveConf.ConfVars.CLIPROMPT),这个参数其实就是hive.cli.prompt,默认是hive,这个其实就是打开客户端,前面有一个hive显示
- 再往后就是executeDriver(ss,conf..)
- 进入executeDriver()方法,先判断执行引擎是否是mr,也可以配置tez,spark程序
- 再往下是setupConsoleReader()初始化控制台阅读器,定义了一个关键的变量,prefix。
- 再往下是while循环阅读readLine阅读每一行,后面是多个if判断,
- 若输入的是一个空串,那么prefix += '\n'
- 若输入的航是以"--"开头的,只能continue,因为这个是注释
- 若是以';'结尾,往下执行解析hql语句 cli.processLine()
- 若不是以';'结尾,prefix+=line,直到读到';'才会解析数据
- 进入processLine()解析sql的方法,前面的代码splitSeiColon(line),对一行按照';'进行切分,因为读取到最后一个字符是';',不一定这一行只有一个分号,返回一个List
- 执行List<string>里的语句,用precessCmd()运行</string>
- processCmd()里有四大内容,第一个是,可以输入exit或者quit退出,并且不会区分大小写;第二部分是输入source,在里面执行一个hql文件;第三部分是以感叹号开头的,以感叹号开头表示执行shell命令;第四部分就是sql的执行,执行方法是processLocalCmd(),里面主要是由一些控制台打印的信息
- 里面运行IDriver.run(cmd,false)的方法
- 里面有parserUtil.parserDriver()方法,parserDriver()将hql转化为token,对token进行解析,生成AST
- 再往后是sem.analyze()方法,SemanticAnaylzer(),将AST转化为QueryBlock,将QUERYBlock转换为OperatorTree,OperatorTree进行逻辑优化生成TaskTree,TaskTree执行物理优化。
- 最后是TaskRunner.runSequential(),ExcDriver(),获取MR临时工作目录,定义Partitioner,定义Mapper和Reducer,实例化job提交job