Hive3 安装(含Hive on Spark)
准备工作
JDK 8 安装
参考《Oracle JDK 安装》笔记内容
ZooKeeper 安装
参考《Zookeeper 集群配置》笔记内容,仅Hadoop3 HA 会用到
Hadoop 3 安装
参考《Hadoop3 集群配置》,《Hadoop3 HA 安装配置》笔记内容
MySQL 5.6 安装
参考《Ubuntu14.04 安装MySQL5.6》笔记内容
Hive3 安装设置
Hive3 下载部署
# 0. 应用准备工作的环境变量
_HIVE_VER=3.1.2
_HIVE_HOST=hadoop114
_HIVE_HOME=/opt/modules/hive-$_HIVE_VER
_MYSQL_HOST=hadoop114
HADOOP_HOME=/opt/modules/hadoop-3.1.3
#HADOOP_HOME=/opt/modules/hadoop-3.2.1
# 1. 下载Hive3
cd && wget https://archive.apache.org/dist/hive/hive-$_HIVE_VER/apache-hive-$_HIVE_VER-bin.tar.gz
# 2. 解压Hive3
cd && tar -xf apache-hive-$_HIVE_VER-bin.tar.gz -C /opt/modules &&\
cd $_ && mv apache-hive-$_HIVE_VER-bin/ $_HIVE_HOME
# 3. 下载MySQL 驱动包到Hive3
wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar -P $_HIVE_HOME/lib
# 4. 替换Hive 中的guava 包
cd $_HIVE_HOME/lib && rename -v 's/.jar/.jar.bak/' guava-*.jar
## rename -v 参数显示重命名的细节信息
cp $HADOOP_HOME/share/hadoop/common/lib/guava-*.jar $_HIVE_HOME/lib
## 通常Hive3 的guava 版本比Hadoop3 的低才需要执行该步骤
ls $_HIVE_HOME/lib | grep ^guava
# 5. 解决日志jar 包冲突
cd $_HIVE_HOME/lib && mv log4j-slf4j-impl-2.10.0.jar log4j-slf4j-impl-2.10.0.jar.bak
hive-env.sh
# Hive 启动需要设置HADOOP_HOME
cat > $_HIVE_HOME/conf/hive-env.sh << EOF
export HADOOP_HOME=$HADOOP_HOME
EOF
hive-site.xml
cat > $_HIVE_HOME/conf/hive-site.xml << EOF
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- MySQL URL,Hive 元数据存在hive3meta 数据库 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<!-- 让hive 自行判断并创建数据库,否则会有问题 -->
<value>jdbc:mysql://$_MYSQL_HOST:3306/hive3meta?createDatabaseIfNotExist=true</value>
</property>
<!-- MySQL 驱动类 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- MySQL 用户名 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<!-- MySQL 密码 -->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
<!-- Hive 存储数据的HDFS 目录,即数据仓库目录 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive3/warehouse</value>
</property>
<!-- 查询结果显示列名 -->
<property>
<name>hive.cli.print.header</name>
<value>true</value>
</property>
<!-- 显示当前数据库名称 -->
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
</property>
<!-- 元数据检查,比较耗内存,测试时关闭,生产中须设为true -->
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<property>
<name>datanucleus.schema.autoCreateAll</name>
<value>true</value>
</property>
<!-- Metastore 服务地址,它是Hive2 之后提供元数据访问的进程 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://$_HIVE_HOST:9083</value>
<!-- 如VALUE 为空即<value/>,Hive 则直连MySQL,无须启动Metastore 进程 -->
</property>
<!-- HiveServer2 可让JDBC、Python 等向Hive 提交任务 -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>$_HIVE_HOST</value>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<property>
<name>hive.metastore.event.db.notification.api.auth</name>
<value>false</value>
</property>
<property>
<name>hive.server2.active.passive.ha.enable</name>
<value>true</value>
</property>
</configuration>
EOF
Hive3 指定队列
注意!hive-site.xml
添加队列信息,Hadoop3
的yarn-site.xml
须有对应的队列信息
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- 在原有可运行配置的基础上加入以下配置 -->
<!-- Hive 在YARN 中的队列信息,这里队列名为hive -->
<property>
<name>mapred.job.queue.name</name>
<value>hive</value>
</property>
<property>
<name>mapreduce.job.queuename</name>
<value>hive</value>
</property>
<property>
<name>mapred.queue.names</name>
<value>hive</value>
</property>
</configuration>
Hive3 启停操作
# 0. 设置环境变量
_HIVE_HOME=/opt/modules/hive-3.1.2
# 1. 初始化MySQL 元数据库,否则后面删库即使能删也会报错,非常重要
ssh hadoop114 <<< 'mysql -uroot -proot -e "drop database if exists hive3meta;"'
cd $_HIVE_HOME && bin/schematool -dbType mysql -initSchema
ssh hadoop114 <<< 'mysql -uroot -proot -e "show databases;"'
## 出现hive3meta 数据库表示初始化成功,详见hive-site.xml
# 2. 启动MetaStore 和HiveServer2 服务
## 2.1 创建日志目录
cd $_HIVE_HOME && mkdir -p log
## 2.2 后台启动服务,重定向 &> 表示stdout 和stderr
nohup $_HIVE_HOME/bin/hive --service metastore &> $_HIVE_HOME/log/metasotre.log &
nohup $_HIVE_HOME/bin/hive --service hiveserver2 &> $_HIVE_HOME/log/hiveserver2.log &
## 如果hive-site.xml 中没有配置hive.metastore.uris 则以上2 个服务进程不需要启动
## 2.3 检查Hive 后台进程
jps -lm
## 31336 org.apache.hadoop.util.RunJar /opt/modules/hive-3.1.2/lib/hive-service-3.1.2.jar org.apache.hive.service.server.HiveServer2
## 31324 org.apache.hadoop.util.RunJar /opt/modules/hive-3.1.2/lib/hive-metastore-3.1.2.jar org.apache.hadoop.hive.metastore.HiveMetaStore
# 3. 启动Hadoop3 集群及MapReduce 历史服务器
HADOOP_HOME=/opt/modules/hadoop-3.1.3
ssh hadoop112 "cd $HADOOP_HOME && sbin/start-dfs.sh"
ssh hadoop113 "cd $HADOOP_HOME && sbin/start-yarn.sh"
ssh hadoop112 "cd $HADOOP_HOME && bin/mapred --daemon start historyserver"
## 如要启动Hadoop3 HA,则先要启动ZooKeeper 集群,再执行以下命令
$HADOOP_HOME/sbin/start-all.sh
# 4. 启动Hive 客户端,退出是exit; 安全退出或quit 直接退出;
cd $_HIVE_HOME && bin/hive
# 5. 停止Hive 后台服务,metastore 及hiveserver2
ps -ef | grep hive | awk '{print $2}' | xargs kill -9
# 6. 停止Hadoop3 集群及MapReduce 历史服务器
HADOOP_HOME=/opt/modules/hadoop-3.1.3
ssh hadoop112 "cd $HADOOP_HOME && sbin/stop-dfs.sh"
ssh hadoop113 "cd $HADOOP_HOME && sbin/stop-yarn.sh"
ssh hadoop112 "cd $HADOOP_HOME && bin/mapred --daemon stop historyserver"
## 如要停止Hadoop3 HA,则先要执行以下命令,再停止ZooKeeper 集群
$HADOOP_HOME/sbin/stop-all.sh
Hive3 服务脚本
针对HiveMetaStore
和HiveServer2
启停的脚本
cd && cat > hive.sh << 'EOF'
#!/bin/bash
_HIVE_HOME=/opt/modules/hive-3.1.2
mkdir -p $_HIVE_HOME/log
status() {
ps -ef | grep -v grep | grep -E 'HiveMetaStore|HiveServer2'
}
start() {
# 如有现有进程则不重复启动,保持单例,&> 表示stderr 和stdout 合并
status &>/dev/null && { echo "Stop HiveMetaStore or HiveServer2 first!"; exit 1; }
# 使用{} 表在当前shell,注意花括号内部和命令之间须有空格,命令以分号结尾,{ CMD1; CMD2; }
nohup $_HIVE_HOME/bin/hive --service metastore &> $_HIVE_HOME/log/metasotre.log &
nohup $_HIVE_HOME/bin/hive --service hiveserver2 &> $_HIVE_HOME/log/hiveserver2.log &
sleep 2 && status &>/dev/null && echo "HiveMetaStore & HiveServer2 started!"
}
stop() {
status | awk '{print $2}' | xargs kill -9
echo "HiveMetaStore & HiveServer2 stopped!"
}
restart() {
stop ; start
}
case $1 in
start) start ;;
stop) stop ;;
status) status ;;
restart) restart ;;
*) echo "Usage: $0 <start|stop|status|restart>" ;;
esac
EOF
# 赋予脚本执行权限x
cd && chmod +x hive.sh
# 使用样例
./hive.sh start # 启动Hive 后台服务
./hive.sh stop # 停止Hive 后台服务
./hive.sh status # 查看Hive 后台服务
./hive.sh restart # 重启Hive 后台服务
# 后台服务正常启动后才可以启动Hive
Hive3 简单使用
-- 0. 启动Hive 客户端
cd /opt/modules/hive-3.1.2 && bin/hive
-- 1. 创建数据库
create database if not exists testdb;
-- 2. 使用数据库
use testdb;
-- 3. 创建表
drop table if exists tb1;
create table tb1(id int, name varchar(32));
-- 4. 插入数据
insert into tb1 values (1, "aaa"), (2, "bbb");
-- 5. 查询数据
select * from tb1;
-- 6. 删除数据库,cascade 表示级联强制删除有数据的库
use default; -- 虽直接删除也可以,但还是切换一下好
drop database testdb cascade;
-- 7. 查看数据库列表
show databases;
-- 8. 退出Hive
quit;
Hive3 on Spark2
概念对比
Hive 引擎包括:默认MR
、Tez
、Spark
Hive on Spark
- Hive 既作为存储元数据又负责SQL 的解析优化,语法是HQL
- Spark 作为执行引擎采用RDD 执行,Spark 要能单独运行,不要求YARN 模式
Spark on Hive
- Hive 只作为存储元数据,Spark 负责SQL 解析优化,语法是Spark SQL
- Spark 负责采用DataFrame、DataSet 执行,详见《Spark SQL Hive LZO 安装配置》
安装Spark2 纯净版
详见《Spark 下载版本的区别》、《Spark 与Hadoop 的YARN 对接》和《Spark 2.4.6 安装及简单使用》
注意:Spark2 为避免和内置的hive
冲突,必须为without-hadoop 版本且和Hive3 在同一个节点上
# 1. 下载Spark2 纯净版
cd && wget https://archive.apache.org/dist/spark/spark-2.4.7/spark-2.4.7-bin-without-hadoop.tgz
# 2. 安装Spark2 纯净版
cd && tar -xf spark-2.4.7-bin-without-hadoop.tgz -C /opt/modules &&\
cd $_ && mv spark-2.4.7-bin-without-hadoop spark-2.4.7-pure
# 3. 删除多余的.cmd 文件
cd /opt/modules/spark-2.4.7-pure && rm -rf */*.cmd
# 4. 配置spark-env.sh
cat > /opt/modules/spark-2.4.7-pure/conf/spark-env.sh << 'EOF'
# HADOOP_HOME 会从hive-env.sh 带过来,这里仅为Spark 单独运行服务
export HADOOP_HOME=/opt/modules/hadoop-3.1.3
# 无论Spark 纯净版还是Hive on Spark 没有SPARK_DIST_CLASSPATH 都不能运行
export SPARK_DIST_CLASSPATH=$(${HADOOP_HOME}/bin/hdfs classpath)
# YARN_CONF_DIR 仅用于Spark 和YARN 对接,跟Hive on Spark 无关
export YARN_CONF_DIR=${HADOOP_HOME}/etc/hadoop
EOF
# 5. 配置spark-defaults.conf,可选
## spark-2.4.7-pure/conf/spark-defaults.conf 对Hive on Spark 没有影响
## 对Hive on Spark 起作用的是hive-3.1.2/conf/spark-defaults.conf 文件
## 也可将spark-defaults.conf 放入写入hive-site.xml,详见之后Hive on Spark 配置
# 6. 测试Spark2 纯净版
cd /opt/modules/spark-2.4.7-pure &&\
bin/run-example SparkPi 2>&1 | grep "Pi is"
## Pi is roughly 3.1480157400787006,确保Spark2 单独运行成功
配置Hive3 on Spark2
hive-env.sh
# 添加SPARK_HOME
cat > /opt/modules/hive-3.1.2/conf/hive-env.sh << 'EOF'
export HADOOP_HOME=/opt/modules/hadoop-3.1.3
# 新增SPARK_HOME 必须是without-hadoop 的纯净版
export SPARK_HOME=/opt/modules/spark-2.4.7-pure
EOF
hive-site.xml
/opt/modules/hive-3.1.2/conf/hive-site.xml
<configuration>
<!-- 在当前可用的基础上添加以下配置 -->
<!-- Spark2 依赖库位置,在YARN 上运行的任务需要从HDFS 中查找依赖jar 文件
${fs.defaultFS} 在Hadoop3 的core-site.xml 中设置,表HDFS 根路径,这里引用即可 -->
<property>
<name>spark.yarn.jars</name>
<!--<value>hdfs://hadoop112:9820/spark2-jars/*</value>-->
<value>${fs.defaultFS}/spark2-jars/*</value>
</property>
<!-- Hive3 执行引擎设为spark -->
<property>
<name>hive.execution.engine</name>
<value>spark</value>
</property>
<!-- Hive3 和Spark2 连接超时时间 -->
<property>
<name>hive.spark.client.connect.timeout</name>
<value>10000ms</value>
</property>
<!-- 将原Spark 配置文件spark-defaults.conf 的内容也可以写在hive-site.xml 这里
例如:原property 形式的内容spark.driver.port 36666 可转换成以下xml 配置形式
或者参考下一节内容创建hive-3.1.2/conf/spark-defaults.conf 以影响Hive on Spark -->
<!--
<property>
<name>spark.driver.port</name>
<value>36666</value>
</property>
-->
</configuration>
spark-defaults.conf
# 1. 创建hive 配置路径下的spark-defaults.conf,注意文件路径
cat > /opt/modules/hive-3.1.2/conf/spark-defaults.conf << 'EOF'
spark.master yarn
# 启用日志聚合
spark.eventLog.enabled true
# 保存日志的HDFS 路径
spark.eventLog.dir hdfs://hadoop112:9820/spark2-history
# 或保存到HDFS HA 的目录,参考core-site.xml 的fs.defaultFS 属性
#spark.eventLog.dir hdfs://hdp3cluster/spark2-history
spark.executor.memory 1g
spark.driver.memory 1g
EOF
## 注意!Hive 切换HDFS 前须先清空当前的元数据,删除所建的表或库等对象
# 2. 创建日志聚合的HDFS 路径
## 汇总保存各个节点上的Spark 日志,须与上面的spark.eventLog.dir 一致
cd /opt/modules/hadoop-3.1.3 && bin/hdfs dfs -mkdir /spark2-history
## 假设Hadoop 3.2.1 配置的是HA 版本
#cd /opt/modules/hadoop-3.2.1 && bin/hdfs dfs -mkdir /spark-history
## 以上命令在某些节点例如hadoop114 上可能会报错,但命令是执行成功的,其等同于以下命令
#cd /opt/modules/hadoop-3.2.1 && bin/hdfs dfs -mkdir hdfs://hdp3cluster/spark-history
Spark2 依赖库
# 1. 去除冲突jar 文件
cd /opt/modules/spark-2.4.7-pure/jars &&\
mv orc-core-1.5.5-nohive.jar orc-core-1.5.5-nohive.jar.bak
# 2. 上传spark2 纯净版依赖库到HDFS
cd /opt/modules/hadoop-3.1.3 &&\
bin/hdfs dfs -rm -r -f /spark2-jars ; bin/hdfs dfs -mkdir /spark2-jars &&\
bin/hdfs dfs -put /opt/modules/spark-2.4.7-pure/jars/* /spark2-jars &&\
bin/hdfs dfs -ls /spark2-jars
## Hive 任务由Spark 执行,Spark 资源分配由Yarn 调度,该任务可能分配到任一个节点
## 所以需要将Spark 的依赖上传到HDFS 集群路径,这样集群中任何一个节点都能获取到
# 3. 复制Spark2 连接依赖库到Hive3
cd /opt/modules/spark-2.4.7-pure/jars && cp \
scala-compiler-2.11.12.jar scala-library-2.11.12.jar scala-reflect-2.11.12.jar \
spark-core_2.11-2.4.7.jar spark-network-common_2.11-2.4.7.jar \
spark-unsafe_2.11-2.4.7.jar spark-yarn_2.11-2.4.7.jar /opt/modules/hive-3.1.2/lib/
# 4. 上传Hive 的orc-core 依赖库
## Spark2 纯净版自带的orc-core-1.5.5-nohive.jar 会造成错误异常
## Job failed with java.lang.NoSuchMethodError: org.apache.orc.TypeDescription.createRowBatch
## 必须将其从HDFS 上/spark2-jars 里删除,因为Hive on Spark 的依赖库来源于HDFS,保险做法就是重命名
cd /opt/modules/hadoop-3.1.3 && bin/hdfs dfs -mv \
/spark2-jars/orc-core-1.5.5-nohive.jar \
/spark2-jars/orc-core-1.5.5-nohive.jar.bak
## 另外还需将Hive 里的orc-core 上传至HDFS 才可以让Spark2 支持ORC 存储格式,详见下一节的测试
cd /opt/modules/hadoop-3.1.3 &&\
bin/hdfs dfs -put /opt/modules/hive-3.1.2/lib/orc-core-1.5.6.jar /spark2-jars
测试Hive3 on Spark2
-- 1. 先启动MetaStore 和HiveServer2 服务,详见Hive3 启停操作或Hive3 服务脚本
-- 如果hive-site.xml 中没有配置hive.metastore.uris 则可跳过本步骤
-- 2. 启动Hive3
cd /opt/modules/hive-3.1.2 && bin/hive
-- 清屏小技巧
!clear;
-- 2.1 查看Hive 引擎
set hive.execution.engine;
-- 结果显示如下,原默认是mr
-- hive.execution.engine=spark
-- 2.2 创建测试表
drop table if exists student;
create table student (id int, name string);
-- 测试Spark 的ORC 支持
drop table if exists student_orc;
create table student_orc (id int, name string) stored as orc;
-- 2.3 插入数据
-- 此时会触发Spark 计算引擎,但只有Map 用于写入磁盘,没有Reduce
insert into student values (1, "zhangsan");
-- 此时访问YARN,http://hadoop113:8088,可看到名为Hive on Spark 的任务
-- 点击其Tracking UI 属性的ApplicationMaster 超链接可进入Spark Web 页面
-- 在Environment 标签下可找到以下属性,表示Spark 已运行在cluster 模式下
-- spark.master yarn
-- spark.submit.deployMode cluster
-- 2.4 如果没有报错并显示结果数据就表示成功了
select * from student;
-- 结果显示
-- student.id student.name
-- 1 zhangsan
-- 需要计算的查询也会触发计算引擎
select count(*) from student where id>1;
-- 2.5 测试Spark 存储ORC 数据
insert into table student_orc select * from student;
select * from student_orc;
select count(*) from student_orc;
-- 2.6 清理数据
drop table student;
drop table student_orc;
-- 2.7 退出hive
quit;
YARN 调度器问题
参考《尚硅谷大数据项目之电商数仓(3电商数据仓库系统)V6.2.4.docx》
3.1.4 Yarn 容量调度器并发度问题演示
调整capacity-scheduler.xml
中yarn.scheduler.capacity.maximum-am-resource-percent
默认YARN
中所有的Application Master
只能使用整个集群10%
的资源,在实际生产环境中是可以的
但是在虚拟机环境中需要调大至50%
,否则Hive on Spark
启动后其他MapReduce
程序都无法运行了
其根本原因就是每个任务都有自己的Application Master
,如果AM
分配不到内存
则任务无法执行下去
参考资料
Hive 安装配置指北
rename 批量重命名文件
Hive 3.1 安装
hive 指定hadoop 执行队列
Hive on Spark 搭建过程
搭建Hive3.1.2 on Spark2.4.7 单机环境