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添加队列信息,Hadoop3yarn-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 服务脚本

针对HiveMetaStoreHiveServer2启停的脚本

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 引擎包括:默认MRTezSpark

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.xmlyarn.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 单机环境

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐