这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
前言
接下来的,我们来学习一个经典的数据仓库 Hive 。
本次采用的 hive版本为3.1.2 , mysql 为8.0.20 .
一、Hive 基本概念
1.1 什么是 Hive
1.1.1 简介
Hive:由Facebook 开源用于解决海量结构化日志的数据统计工具和数据分析工具
Hive:是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。
1.1.2 Hive 本质
Hive的本质就是将结构化的数据映射成一张表,底层还是通过MR作为计算引擎,HDFS作为存储,YARN作为资源调度。
a、Hive 处理的数据存储在HDFS
b、Hive 分析数据底层的实现是 MapReduce
c、执行程序允许在 yarn 上。
1.2 Hive 的优缺点
1.2.1 优点
(1)操作接口采用类SQL语法,提供快速开发的能力
(2)避免了去写MapReduce,减少开发学习成本
(3)Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合
(4)Hive的优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高
(5)Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数
1.2.2 缺点
(a)Hive的HQL表达能力有限
- (1)迭代式算法无法表达
- (2)数据挖掘方面不擅长,由于MapReduce数据处理流程的限制,效率更高的算法却无法实现
(b)Hive的效率比较都低
- (1)Hive自动生成的MapReduce作业,通常情况下不够智能化
- (2)Hive 调优比较困难,粒度较粗
1.3 Hive 架构原理
Hive计算的数据存储在HDFS
Hive的元数据信息(表的信息)存储在第三方的数据库中,默认使用的derby,换成mysql,可以多开几个客户端窗口。
- 用户接口:Client
CLI(command-line interface)、JDBC/ODBC(jdbc访问hive)、WEBUI(浏览器访问hive)
- 元数据:Metastore
元数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;
默认存储在自带的derby数据库中,推荐使用MySQL存储Metastore
- Hadoop
使用HDFS进行存储,使用MapReduce进行计算。
-
驱动器:Driver
- (1)解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
- (2)编译器(Physical Plan):将AST编译生成逻辑执行计划。
- (3)优化器(Query Optimizer):对逻辑执行计划进行优化。
- (4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于Hive来说,就是MR/Spark。
Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口。
1.4 Hive 和数据库比较
由于 Hive 采用了类似SQL 的查询语言 HQL(Hive Query Language),因此很容易将 Hive 理解为数据库。其实从结构上来看,Hive 和数据库除了拥有类似的查询语言,再无类似之处。本文将从多个方面来阐述 Hive 和数据库的差异。数据库可以用在 Online 的应用中,但是Hive 是为数据仓库而设计的,清楚这一点,有助于从应用角度理解 Hive 的特性。
1.4.1 查询语言
由于SQL被广泛的应用在数据仓库中,因此,专门针对Hive的特性设计了类SQL的查询语言HQL。熟悉SQL开发的开发者可以很方便的使用Hive进行开发。
1.4.2 数据更新
由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive中不建议对数据的改写,所有的数据都是在加载的时候确定好的。而数据库中的数据通常是需要经常进行修改的,因此可以使用 INSERT INTO … VALUES 添加数据,使用 UPDATE … SET修改数据。
1.4.3 执行延迟
Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高。另外一个导致 Hive 执行延迟高的因素是 MapReduce框架。由于MapReduce 本身具有较高的延迟,因此在利用MapReduce 执行Hive查询时,也会有较高的延迟。相对的,数据库的执行延迟较低。当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive的并行计算显然能体现出优势。
1.4.4 数据规模
由于Hive建立在集群上并可以利用MapReduce进行并行计算,因此可以支持很大规模的数据;对应的,数据库可以支持的数据规模较小。
二、Hive 安装
2.1 Hive 安装地址
- hive 官网 : hive.apache.org/
- 文档查看地址:cwiki.apache.org/confluence/…
- 下载地址:archive.apache.org/dist/hive/
- github 地址:github.com/apache/hive
2.2 Mysql 安装
hive 需要借助 mysql 来存储 metadata 元数据,所以需要安装 mysql 并配置 mysql。
mysql 的安装之前写过两篇文章了,分别是 rpm 安装和源码安装。
但下面,我将用yum 来安装,效率是前两者的 n 倍,建议自己搭建环境的时候可以使用。
1、安装 Mysql8.0 资源库
yum localinstall https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm
2、安装 Mysql 8.0
yum install mysql-community-server
3、启动 Mysql 并配置开机自启
systemctl start mysqld
systemctl enable mysqld
4、查看默认密码并重置
grep 'temporary password' /var/log/mysqld.log
登录并更改密码:注意-p 和密码之间不能用空格
[root@hadoop101 package]# mysql -p+TkQU4tYowE6
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.25
5、更改密码,授予远程权限:
mysql> alter user 'root'@'localhost' IDENTIFIED with mysql_native_password by 'Admin12@2021';
Query OK, 0 rows affected (0.00 sec)
mysql> rename user 'root'@'localhost' to 'root'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges on *.* to 'root'@'%';
Query OK, 0 rows affected (0.00 sec)
6、远程访问即可
2.3 Hive 部署
2.3.1 hive 安装
根据上面网址下载 hive 版本,我下载的是 apache-hive-3.1.2-bin.tar.gz 。
-
1、将 hive 的 jar 包上传到 linux 的 /opt/package
-
2、解压 apache-hive-3.1.2-bin.tar.gz 到 /opt/software,然后重命名为 hive
tar -zxvf /opt/software/apache-hive-3.1.2-bin.tar.gz -C /opt/module/ mv apache-hive-3.1.2-bin/ hive
-
3、修改 /etc/profile.d/my_env.sh , 添加环境变量
vim /etc/profile
#HIVE_HOMEHIVE_HOME=/opt/module/hivePATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/binexport PATH JAVA_HOME HADOOP_HOME HIVE_HOME
-
4、进入 lib 目录 解决 日志 jar 包冲突
[leilei@hadoop100 lib]$ mv log4j-slf4j-impl-2.10.0.jar log4j-slf4j-impl-2.10.0.bak
2.3.2 Hive 元数据配置到 Mysql
-
1、下载 mysql 的连接驱动,我的mysql 为 8.0.25 最新款,所以需要下载该版本的驱动,下载连接为:dev.mysql.com/downloads/f…
-
2、把下载的 mysql 的 JDBC 驱动拷贝到 hive 的lib 目录下:
<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="configuration.xsl"?><configuration> <!-- jdbc连接的URL --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://hadoop101:3306/metastore?userSSL=false</value> </property> <!-- jdbc连接的Driver--> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.cj.jdbc.Driver</value> </property> <!-- jdbc连接的username--> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <!-- jdbc连接的password --> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>Admin@2021</value> </property> <!-- Hive默认在HDFS的工作目录 --> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive/warehouse</value> </property> <!-- Hive元数据存储版本的验证 --> <property> <name>hive.metastore.schema.verification</name> <value>false</value> </property> <!-- 指定存储元数据要连接的地址 --> <property> <name>hive.metastore.uris</name> <value>thrift://hadoop101:9083</value> </property> <!-- 指定hiveserver2连接的端口号 --> <property> <name>hive.server2.thrift.port</name> <value>10000</value> </property> <!-- 指定hiveserver2连接的host --> <property> <name>hive.server2.thrift.bind.host</name> <value>hadoop101</value> </property> <!-- 元数据存储授权 --> <property> <name>hive.metastore.event.db.notification.api.auth</name> <value>false</value> </property> </configuration>
2.3.3 初始化元数据库
-
1、创建 mysql 的库 metastore ,用来存放 hive 的元数据的表。
-
2、初始化 hive 元数据库,这个过程,会在mysql 的对应的数据库中添加 hive 的相关信息
cd hive/bin[root@hadoop101 bin]# ./schematool -initSchema -dbType mysql -verbose
完成之后,我们可与发现这个数据库中多出了很多张表。
2.4 启动 hive
2.4.1 启动 metastore 和 hiveserver2
这两个服务可以直接启动,例如下面的命令,但是启动后窗口不能再操作了,也不能关闭当前窗口,所以我们不推荐这种方式。
hive --service metastorehive --service hiveserver2
下面,我们通过后台方式启动,一般采用组合命令:nohup [xxx 命令操作] >file 2>&1% 。表示将xxx 命令运行的结果输出到 file 中,并保持命令启动的进程在后台运行。
[root@hadoop101 hive]# nohup hive --service metastore 2>&1 &[1] 108879[root@hadoop101 hive]# nohup hive --service hiveserver2 2>&1 &[2] 109675
为了更加方便,我们通过脚本来管理服务的启动和关闭,脚本的编写不要求掌握,直接拿来使用即可。注意路径即可
vim $HIVE_HOME/bin/hiveservices.sh
#!/bin/bash
HIVE_LOG_DIR=$HIVE_HOME/logs
if [ ! -d $HIVE_LOG_DIR ]
then
mkdir -p $HIVE_LOG_DIR
fi
#检查进程是否运行正常,参数1为进程名,参数2为进程端口
function check_process()
{
pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print $2}')
ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -d '/' -f 1)
echo $pid
[[ "$pid" =~ "$ppid" ]] && [ "$ppid" ] && return 0 || return 1
}
function hive_start()
{
metapid=$(check_process HiveMetastore 9083)
cmd="nohup hive --service metastore >$HIVE_LOG_DIR/metastore.log 2>&1 &"
cmd=$cmd" sleep 4; hdfs dfsadmin -safemode wait >/dev/null 2>&1"
[ -z "$metapid" ] && eval $cmd || echo "Metastroe服务已启动"
server2pid=$(check_process HiveServer2 10000)
cmd="nohup hive --service hiveserver2 >$HIVE_LOG_DIR/hiveServer2.log 2>&1 &"
[ -z "$server2pid" ] && eval $cmd || echo "HiveServer2服务已启动"
}
function hive_stop()
{
metapid=$(check_process HiveMetastore 9083)
[ "$metapid" ] && kill $metapid || echo "Metastore服务未启动"
server2pid=$(check_process HiveServer2 10000)
[ "$server2pid" ] && kill $server2pid || echo "HiveServer2服务未启动"
}
case $1 in
"start")
hive_start
;;
"stop")
hive_stop
;;
"restart")
hive_stop
sleep 2
hive_start
;;
"status")
check_process HiveMetastore 9083 >/dev/null && echo "Metastore服务运行正常" || echo "Metastore服务运行异常"
check_process HiveServer2 10000 >/dev/null && echo "HiveServer2服务运行正常" || echo "HiveServer2服务运行异常"
;;
*)
echo Invalid Args!
echo 'Usage: '$(basename $0)' start|stop|restart|status'
;;
esac
给这个脚本添加执行权限:
[root@hadoop101 hive]# chmod +x $HIVE_HOME/bin/hiveservices.sh
启动 Hive 后台服务:
hiveservices.sh start
2.4.2 启动集群
执行我们编写的脚本
[root@hadoop101 sbin]# mycluster.sh start
看到启动的服务是否正常:
[root@hadoop101 sbin]# myjps.sh
===== hadoop101 jps======
18993 DataNode
122563 RunJar
20882 Jps
122123 RunJar
20619 NodeManager
18813 NameNode
===== hadoop102 jps======
39191 NodeManager
37848 DataNode
39002 ResourceManager
39677 Jps
===== hadoop103 jps======
26724 Jps
25333 DataNode
25482 SecondaryNameNode
26463 NodeManager
[root@hadoop101 sbin]# hiveservices.sh status
Metastore服务运行正常
HiveServer2服务运行正常
2.5 Hive 访问
2.5.1 HiveJDBC 访问
$HIVE_HOME/bin/beeline -u jdbc:hive2://hadoop101:10000 -n root
出现下面的界面信息表示访问 Hive 成功!
[root@hadoop101 hadoop]# $HIVE_HOME/bin/beeline -u jdbc:hive2://hadoop101:10000 -n rootConnecting to jdbc:hive2://hadoop101:10000Connected to: Apache Hive (version 3.1.2)Driver: Hive JDBC (version 3.1.2)Transaction isolation: TRANSACTION_REPEATABLE_READBeeline version 3.1.2 by Apache Hive0: jdbc:hive2://hadoop101:10000>
如果启动失败:
- 1、查看 hiveserver2 服务是否正常运行
- 2、查看 hadoop 的etc/hadoop/core-site.xml 中是否加兼容配置,让任意用户都需要代理这个用户去访问
<!-- 下面是兼容性配置,先跳过 --> <!-- 配置该root(superUser)允许通过代理访问的主机节点 --> <property> <name>hadoop.proxyuser.root.hosts</name> <value>*</value> </property> <!-- 配置该root(superuser)允许代理的用户所属组 --> <property> <name>hadoop.proxyuser.root.groups</name> <value>*</value> </property> <!-- 配置该root(superuser)允许代理的用户--> <property> <name>hadoop.proxyuser.root.users</name> <value>*</value> </property>
2.5.2 Hive 客户端访问
- 1、启动 Hive 客户端
[root@hadoop101 sofeware]# hivewhich: no hbase in (/opt/rh/devtoolset-9/root/usr/bin:/opt/sofeware/java8/bin:/opt/sofeware/java8/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/sofeware/hadoop-3.1.3/bin:/opt/sofeware/hadoop-3.1.3/sbin:/opt/sofeware/hive/bin:/home/lei/bin:/root/bin)Hive Session ID = fb510c68-35b2-4505-86c6-f962b3dbdedbLogging initialized using configuration in jar:file:/opt/sofeware/hive/lib/hive-common-3.1.2.jar!/hive-log4j2.properties Async: trueHive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.Hive Session ID = 8f32c100-e1d7-4313-8bea-3b72441ab1cehive>
可以看到一些打印信息,现在使用的引擎是MR ,已经过时了,后面可以更换。
-
2、查看数据库
hive> show databases;OKdefaultTime taken: 0.517 seconds, Fetched: 1 row(s)
-
3、为了打印信息美观点,我们可以在hive-site .xml 中加入如下两个配置:
<property> <name>hive.cli.print.header</name> <value>true</value> <description>Whether to print the names of the columns in query output.</description> </property> <property> <name>hive.cli.print.current.db</name> <value>true</value> <description>Whether to include the current database in the Hive prompt.</description> </property>
-
4、最终效果也不是太明显,加了表头和所在库,美观程度不及 beeline。推荐上面那种方式访问
hive (default)> create database mydb;OKTime taken: 1.209 secondshive (default)> use mydb;OKTime taken: 0.057 secondshive (mydb)> show databases;OKdatabase_namedefaultmydb
2.6 Hive 交互命令
[root@hadoop101 conf]# hive -helpwhich: no hbase in (/opt/rh/devtoolset-9/root/usr/bin:/opt/sofeware/java8/bin:/opt/sofeware/java8/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/sofeware/hadoop-3.1.3/bin:/opt/sofeware/hadoop-3.1.3/sbin:/opt/sofeware/hive/bin:/home/lei/bin:/root/bin)Hive Session ID = e8e97f61-a6de-440e-be53-8f3e1592414fusage: hive -d,--define <key=value> Variable substitution to apply to Hive commands. e.g. -d A=B or --define A=B --database <databasename> Specify the database to use -e <quoted-query-string> SQL from command line -f <filename> SQL from files -H,--help Print help information --hiveconf <property=value> Use value for given property --hivevar <key=value> Variable substitution to apply to Hive commands. e.g. --hivevar A=B -i <filename> Initialization SQL file -S,--silent Silent mode in interactive shell -v,--verbose Verbose mode (echo executed SQL to the console)
-
1、“-e” 不进入 hive 的交互窗口 执行 SQL 语句
[root@hadoop101 ~]# bin/hive -e "select * from mydb.mytable;"-bash: bin/hive: 没有那个文件或目录[root@hadoop101 ~]# hive -e "select * from mydb.mytable;"which: no hbase in (/opt/rh/devtoolset-9/root/usr/bin:/opt/sofeware/java8/bin:/opt/sofeware/java8/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/sofeware/hadoop-3.1.3/bin:/opt/sofeware/hadoop-3.1.3/sbin:/opt/sofeware/hive/bin:/home/lei/bin:/root/bin)Hive Session ID = 05e49b32-b3d3-4e8e-bf01-64293c905fa6Logging initialized using configuration in jar:file:/opt/sofeware/hive/lib/hive-common-3.1.2.jar!/hive-log4j2.properties Async: trueHive Session ID = 539ebc53-ff74-4def-b715-321edbe50966OKmytable.id mytable.nameTime taken: 2.709 seconds
-
2、“- f ” 执行脚本中 sql 语句
-
- 创建hive.sql ,在里面编写sql 文件
-
- 执行文件中的 sql 文件,然后输出文件的结果到某个结果文件中
hive -f hivef.sql > /opt/module/datas/hive_result.txt
-
2.7 Hive 其他命令操作
-
1、退出 Hive窗口
hive(default)>exit;hive(default)>quit;
在老版本中这两者是有区别的:
- exit :先隐性提交数据,再推出
- quit:不提交数据,退出。
-
2、在hive cli 命令窗口中如何查看 hdfs文件系统
hive(default)>dfs -ls /;
-
3、查看在 hive 中输入的所有历史命令
- 1、进入到当前用户的根目录 /root 或 /home/lei
- 2、查看 .hivehistory 文件
2.8 Hive 常见属性配置
2.8.1 Hive 运行日志信息配置
-
1、Hive 的 log 默认存放在 /tep/root/hive.log 目录下(当前用户名下)
-
2、修改 hive 的log 存放日志到 /opt/software/hive/logs 中
- 1、修改hive /conf/hive-log4j.properties.template 文件名称为 hive-log4j.properties
[root@hadoop101 conf]# mv hive-log4j2.properties.template hive-log4j2.properties[root@hadoop101 conf]# vim hive-log4j2.properties
- 2、修改里面的配置
property.hive.log.dir = /opt/software/hive/logs
2.8.2 参数设置方式
-
1、查看当前所有的配置信息
hive > set
-
2、参数的配置三种方式
-
1、配置文件方式
- 默认的配置文件是:hive-defalut.xml
- 用户自定义配置文件:hive-site.xml
- 注意:用户自定义配置会覆盖默认配置,另外 Hive也会读入 Hadoop的配置,因为 Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖 hadoop 的配置。
-
2、命令行参数方式
- 启动 Hive 时,可与在命令行添加 -hiveconf param=value 来设定参数,仅对本次 hive启动有效
hive -hiveconf mapred.reduce.tasks=10;
-
查看参数设置:
hive (default)> set mapred.reduce.tasks;
-
3、参数声明方式
可以在 HQL 中使用 SET 关键字设定参数, 仅对本次 hive 启动有效。
hive (default)> set mapred.reduce.tasks=100;
上述三种设定方式的优先级依次递增。即配置文件<命令行参数<参数声明。注意某些系统级的参数,例如log4j相关的设定,必须用前两种方式设定,因为那些参数的读取在会话建立以前已经完成了
-