一、准备工作
hive本身支持hive on mr、hive on spark 和hive on tez三种执行引擎,CDH6.3.x及其以下版本都没有支持tez执行引擎,需要使用的话需要单独引入。由于CDH的hadoop版本进行了改造,因此tez的开源release版本不能直接使用,需要集成CDH的hadoop版本。
1、下载tez的源码进行编译
http://www.apache.org/dyn/closer.lua/tez/0.9.2/
2、源码编译过程中hadoop中需要使用protobuf,需要下载protobuf-2.5.0
https://github.com/protocolbuffers/protobuf/releases
其中window版本使用protoc-2.5.0-win32.zip,直接解压,然后配置到环境变量中就可以了。
liunx版本使用protobuf-2.5.0.tar.gz
3、使用window编译,需要下载git bash,然后使用git命令来编译
二、编译tez
1、将apache-tez-0.9.2-src.tar.gz解压,然后使用idea修改pom配置,第一处为修改,其余为添加
第一处: <hadoop.version>3.0.0-cdh6.3.2</hadoop.version> 第二处: <repository> <id>cloudera</id> <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url> <name>Cloudera Repositories</name> <snapshots> <enabled>false</enabled> </snapshots> </repository> 第三处: <pluginRepository> <id>cloudera</id> <name>Cloudera Repositories</name> <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url> </pluginRepository> 第四处: <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.19</version> </dependency> 第五处: <!--<module>tez-ext-service-tests</module> <module>tez-ui</module>--> 注:将这两个注释掉,如果有需要可以不用注释
2、修改mapreduce的java文件
报错:tez-mapreduce编译时,报ApplicationReport.newInstance() 89行异常,使用另一个方法newInstance()方法
vim tez-mapreduce/src/main/java/org/apache/tez/mapreduce/client/NotRunningJob.java
return ApplicationReport.newInstance(unknownAppId, unknownAttemptId, "N/A", "N/A", "N/A", "N/A", 0, null, YarnApplicationState.NEW, "N/A", "N/A", 0, 0, 0, FinalApplicationStatus.UNDEFINED, null, "N/A", 0.0f, "TEZ_MRR", null); 注:可以先进行编译,如果报这个错再进行修改这一步也行
3、使用git bash进入到源码目录,然后执行如下maven命令编译
mvn clean package -Dmaven.javadoc.skip=true -Dmaven.test.skip=true
注:这样会跳过test编译,很快就编译完成
4、编译完后的地址,cd tez-dist/target
三、集成到CDH6.3.2版本中
1、将tez的jar包上传到hdfs中
1. 创建目录
hadoop fs -mkdir /tez 2. 上传到hdfs
hadoop fs -put tez-0.9.2.tar.gz /tez
2、将tez整合到hive中,集群中的每台服务器都需要操作
1.进到cdh的lib包目录
cd /opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib 2.创景tez目录
mkdir tez 3.创建tez配置文件
vim tez-site.xml
<configuration> <property> <name>tez.lib.uris</name> <value>${fs.defaultFS}/apps/tez-0.9.1/tez-0.9.1.tar.gz</value> </property> <property> <name>tez.use.cluster.hadoop-libs</name> <value>false</value> </property>
<property>
<name>tez.am.launch.env</name>
<value>LD_LIBRARY_PATH=${PARCELS_ROOT}/CDH/lib/hadoop/lib/native</value>
</property>
<property>
<property>
<name>tez.task.launch.env</name>
<value>LD_LIBRARY_PATH=${PARCELS_ROOT}/CDH/lib/hadoop/lib/native</value>
</property>
</configuration>
3、拷贝jar包
tez-0.9.2-minimal文件夹下的jar及lib下的jar拷贝到tez中
4、避免kryo的错误:
java.lang.NoClassDefFoundError: com/esotericsoftware/shaded/org/objenesis/strategy/InstantiatorStrategy
4.1 cd /opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib/hive/auxlib
4.2 mv hive-exec-2.1.1-cdh6.3.2-core.jar hive-exec-2.1.1-cdh6.3.2-core.jar.bck
4.3 mv hive-exec-core.jar hive-exec-core.jar.bck
4.4 从 /opt/cloudera/parcels/CDH-6.0.1-1.cdh6.0.1.p0.590678/jars中拷贝kryo-2.22.jar到tez文件夹下的lib文件夹下,防止出现以下异常:
java.lang.ClassNotFoundException: com.esotericsoftware.kryo.Serializer
4.5 tez/lib中包含slf4j的jar包,会打印较多日志,可以在客户端中去掉slf4j-api-1.7.10.jar、slf4j-log4j12-1.7.10.jar这两个jar包,减少日志打印,
5、配置hive的env配置文件
5.1 添加:HADOOP_CLASSPATH=/opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib/tez/conf:/opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib/tez/*:/opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.1605554/lib/tez/lib/*
5.2 部署客户端配置
5.3 重启需要组件
内容如下:
HADOOP_CLASSPATH=/opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.590678/lib/tez/conf:/opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.590678/lib/tez/*:/opt/cloudera/parcels/CDH-6.3.2-1.cdh6.3.2.p0.590678/lib/tez/lib/*
然后保存并部署客户端配置,这样配置的环境变量才会生效。
6、测试
hive //进入hive cli
hive> set hive.tez.container.size=3020;
hive> set hive.execution.engine=tez;
执行left join的语句
SELECT
A.CalDate,
A.InnerCode,
A.SecuCode,
A.SecuAbbr,
A.SecuMarket,
A.RuleCode,
A.RuleDesc,
2 AS DataFlag
FROM TMP_DWD_PC_INT_ZM_StockPoolComponent A
JOIN DWD_PC_INT_ZM_StockPoolComponent B ON A.CalDate=B.CalDate AND A.RuleCode=B.RuleCode AND A.SecuCode=B.SecuCode AND NVL(A.SecuMarket,0)=NVL(B.SecuMarket,0)
AND B.DELDATE='99991231'
WHERE NVL(A.InnerCode,0)<>NVL(B.InnerCode,0)
OR NVL(A.SecuAbbr,'')<>NVL(B.SecuAbbr,'')
OR NVL(A.RuleDesc,'')<>NVL(B.RuleDesc,'');