G:\Bigdata\2.hive\大数据技术之Hive源码编译
Hadoop3.3.1
Hive3.1.3
Spark3.3.1
Hive on spark / spark on hive 均验证通过。
第1章 部署Hadoop和Hive
1.1 版本测试
Hadoop3.3.6 和Hive3.1.3
运行hive客户端时报错:
java.lang.NoSuchMethodError:com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V
查看Hadoop在Github上的pom依赖,在hadoop-project模块中:
hadoop/hadoop-project/pom.xml at rel/release-3.3.6 · apache/hadoop · GitHub
查看Hive的Guava依赖:
hive/pom.xml at rel/release-3.1.3 · apache/hive · GitHub
Hadoop启动后调用了guava-27中的一些方法,而Hive在启动时,它的JVM中加载的是guava-19这个版本,而这版本中就没有这个方法。
第2章 Hadoop和Hive的兼容性问题
2.1 问题原因
上述问题是由Hadoop3.1.3版本所依赖的guava-27.0-jre和Hive-3.1.3版本所依赖的guava-19.0不兼容所致。
2.2 解决思路
1)更换Hadoop版本
经过观察发现,Hadoop-3.1.0,Hadoop-3.1.1,Hadoop-3.1.2版本的guava依赖均为guava-11.0.2,而到了Hadoop-3.1.3版本,guava依赖的版本突然升级到了guava-27.0-jre。
Hive-3的所有发行版本的guava依赖均为guava-19.0。而guava-19.0和guava-11.0.2版本是兼容的,所以理论上降低Hadoop版本,这个问题就能得到有效的解决。
通过对github上源码的提交记录,可以找到跟guava相关的信息:branch 选择Hadoop rel/3.1.3
找到hadoop-project的pom.xml, 点击history,搜索guava
点进去之后发现这个升级跟guava的漏洞CVE-018-10237有关:
继续搜索这个漏洞的详细信息,发现里面描述的这个guava漏洞从guava11.0 一直到guava-24版本都存在,因此Hadoop才从3.1.3一下子升级到guava-27.
2)升级Hive-3.1.3中的guava依赖版本,并重新编译Hive
若将Hive-3.1.3中的guava依赖版本升级到guava-27.0-jre,这样就能避免不同版本的guava依赖冲突,上述问题同样能得到解决。
2.3 解决实操
此处,我们选择升级Hive-3.1.3中的guava依赖版本,所以我们需要拉取Hive源码进行修改并重新编译。由于Hive源码的编译工作需要在Linux系统中进行,同时我们需要修改Hive的源码,所以我们需要一个合适的操作环境。
2.3.1 搭建编译环境
1)虚拟机准备
准备一台虚拟机,并安装Centos7.9系统(带桌面环境)。
2)安装JDK
(1)卸载现有JDK
[seven@hadoop100 opt]# sudo rpm -qa | grep -i java | xargs -n1 sudo rpm -e --nodeps
ubuntu写作Java:
1. 确定已安装的Java版本:首先要确定系统默认安装的Java版本。可以使用以下命令检查系统中已安装的Java版本:
```bash
java -version
```2. 卸载Java:根据系统中已安装的Java版本,选择对应的命令进行卸载。
- 如果系统中是 OpenJDK,请使用以下命令卸载:
```
sudo apt-get remove openjdk-\*
```- 如果系统中是 Oracle Java,请使用以下命令卸载:
```bash
sudo apt-get remove --purge oracle-java\*
```3. 清除残留文件:除了执行卸载命令之外,你也可以运行以下命令来清理残留文件:
```bash
sudo apt-get autoremove
```4. 验证卸载:最后,你可以再次运行 `java -version` 命令来确认Java已被成功卸载。
请注意,在卸载Java之前,请确保你不再需要系统自带的Java,并且可以自行安装其他版本的Java或者 OpenJDK。
(2)将JDK上传到虚拟机的/opt/software文件夹下面
(3)解压JDK到/opt/module目录下
[seven@hadoop100 software]# tar -zxvf jdk-8u212-linux-x64.tar.gz -C /opt/module/
(4)配置JDK环境变量
1 新建/etc/profile.d/my_env.sh文件
[seven@hadoop100 module]# sudo vim /etc/profile.d/my_env.sh
添加如下内容,然后保存(:wq)退出
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_212
export PATH=$PATH:$JAVA_HOME/bin
2 让环境变量生效
[seven@hadoop100 software]$ source /etc/profile.d/my_env.sh
(5)测试JDK是否安装成功
[seven@hadoop100 module]# java -version
如果能看到以下结果,则Java正常安装
java version "1.8.0_212"
3)安装Maven
(1)将Maven安装包上传到虚拟机/opt/software目录
(2)解压Maven到/opt/module目录下
[seven@hadoop100 software]$ tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /opt/module/
(3)配置Maven环境变量
1 编辑/etc/profile.d/my_env.sh文件
[seven@hadoop100 module]$ sudo vim /etc/profile.d/my_env.sh
追加以下内容
# MAVEN_HOME
export MAVEN_HOME=/opt/module/apache-maven-3.6.3
export PATH=$PATH:$MAVEN_HOME/bin
2 让环境变量生效
[seven@hadoop100 software]$ source /etc/profile.d/my_env.sh
(4)检测Maven是否安装成功
[seven@hadoop100 module]$ mvn -version
如果能看到以下结果,则Maven正常安装
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /opt/module/apache-maven-3.6.3
Java version: 1.8.0_212, vendor: Oracle Corporation, runtime: /opt/module/jdk1.8.0_212/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-862.el7.x86_64", arch: "amd64", family: "unix"
(5)配置仓库镜像
1 修改Maven配置文件
[seven@hadoop100 ~]$ vim /opt/module/apache-maven-3.6.3/conf/settings.xml
2 在<mirrors></mirrors>节点中增加以下内容
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
4)安装Git
(1)安装第三方仓库
[seven@hadoop100 ~]$ sudo yum install https://repo.ius.io/ius-release-el7.rpm https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
(2)安装Git
[seven@hadoop100 ~]$ sudo yum install -y git236
5)安装IDEA
(1)将IDEA安装包上传到虚拟机/opt/software目录
(2)解压IDEA到/opt/module目录下
[seven@hadoop100 software]$ tar -zxvf ideaIU-2021.1.3.tar.gz -C /opt/module/
(3)启动IDEA(在图形化界面启动)
[seven@hadoop100 ~]$ nohup /opt/module/idea-IU-211.7628.21/bin/idea.sh 1>/dev/null 2>&1 &
(4)配置Maven
2.3.2 修改并编译Hive源码
1)在IDEA中新建项目拉取Hive源码
Hive源码的远程仓库地址:
https://github.com/apache/hive.git
国内镜像地址:
hive: Hive是一个基于Hadoop的数据仓库平台
2)测试编译环境
在修改依赖和代码之前,先测试一下打包是否能成功,用来检测环境是否正常。
LanguageManual - Apache Hive - Apache Software Foundation
在hive的UserMannual中找到编译相关的信息:
mvn clean package -Pdist [-DskipTests -Dmaven.javadoc.skip=true]
实际测试结果:
(1)打开终端
(2)输入打包命令
mvn clean package -Pdist -DskipTests -Dmaven.javadoc.skip=true
注:打包命令参考官网
https://cwiki.apache.org/confluence/display/Hive/GettingStarted#GettingStarted-CompileHiveonmaster
打包成功的标志如下:
4)修改Maven父工程的pom.xml文件中的guava.version参数
将
<guava.version>19.0</guava.version>
改为
<guava.version>27.0-jre</guava.version>
5)重新执行Hive的编译打包命令,并根据错误提示修改代码
mvn clean package -Pdist -DskipTests -Dmaven.javadoc.skip=true
打包成功后目标文件所在目录:
seven@ubuntu:~/IdeaProjects/hive/packaging/target
6)反复执行上一步骤,直至编译打包成功
注:以下文件是根据修改guava版本的相关内容制作的补丁,可应用该补丁快速修改代码。
guava-27.0-jre.patch
From b611fdd410be34a7c07b9adc29328119269aa6da Mon Sep 17 00:00:00 2001
From: atguigu <email@atguigu.com>
Date: Thu, 1 Sep 2022 00:31:59 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7guava=E4=BE=9D=E8=B5=96?==?UTF-8?q?=E7=89=88=E6=9C=AC=E8=87=B327.0-jre?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit---.../hive/druid/serde/DruidScanQueryRecordReader.java | 3 ++-.../org/apache/hadoop/hive/llap/AsyncPbRpcProxy.java | 4 ++--.../hadoop/hive/llap/daemon/impl/AMReporter.java | 6 +++---.../hive/llap/daemon/impl/LlapTaskReporter.java | 2 +-.../hive/llap/daemon/impl/TaskExecutorService.java | 2 +-.../llap/tezplugins/LlapTaskSchedulerService.java | 6 +++---pom.xml | 2 +-.../hadoop/hive/ql/exec/tez/WorkloadManager.java | 12 ++++--------.../hive/ql/exec/tez/SampleTezSessionState.java | 8 +++-----9 files changed, 20 insertions(+), 25 deletions(-)diff --git a/druid-handler/src/java/org/apache/hadoop/hive/druid/serde/DruidScanQueryRecordReader.java b/druid-handler/src/java/org/apache/hadoop/hive/druid/serde/DruidScanQueryRecordReader.java
index 64c640f45a..6b9f08cd8a 100644
--- a/druid-handler/src/java/org/apache/hadoop/hive/druid/serde/DruidScanQueryRecordReader.java
+++ b/druid-handler/src/java/org/apache/hadoop/hive/druid/serde/DruidScanQueryRecordReader.java
@@ -28,6 +28,7 @@import com.google.common.collect.Iterators;import java.io.IOException;
+import java.util.Collections;import java.util.Iterator;import java.util.List;@@ -43,7 +44,7 @@private ScanResultValue current;- private Iterator<List<Object>> compactedValues = Iterators.emptyIterator();
+ private Iterator<List<Object>> compactedValues = Collections.emptyIterator();@Overrideprotected JavaType getResultTypeDef() {
diff --git a/llap-common/src/java/org/apache/hadoop/hive/llap/AsyncPbRpcProxy.java b/llap-common/src/java/org/apache/hadoop/hive/llap/AsyncPbRpcProxy.java
index ad39963614..1ece28c0f2 100644
--- a/llap-common/src/java/org/apach