第 1 章 Hive 基本概念

1) hive 简介
Hive:由 Facebook 开源用于解决海量结构化日志的数据统计工具。 Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并 提供类 SQL 查询功能。
2) Hive 本质:将 HQL 转化成 MapReduce 程序
image.png
(1)Hive 处理的数据存储在 HDFS
(2)Hive 分析数据底层的实现是 MapReduce
(3)执行程序运行在 Yarn 上

1.2Hive 的优缺点

1.2.1 优点
(1)操作接口采用类 SQL 语法,提供快速开发的能力(简单、容易上手)。
(2)避免了去写 MapReduce,减少开发人员的学习成本。
(3)Hive 的执行延迟比较高,因此 Hive 常用于数据分析,对实时性要求不高的场合。
(4)Hive 优势在于处理大数据,对于处理小数据没有优势,因为 Hive 的执行延迟比较 高。
(5)Hive 支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
1.2.2 缺点
1)Hive 的 HQL 表达能力有限
(1)迭代式算法无法表达
(2)数据挖掘方面不擅长,由于 MapReduce 数据处理流程的限制,效率更高的算法却
无法实现。
2)Hive 的效率比较低
(1)Hive 自动生成的 MapReduce 作业,通常情况下不够智能化
(2)Hive 调优比较困难,粒度较粗

1.3 Hive 架构原理

image.png
1)用户接口:Client
CLI(command-line interface)、JDBC/ODBC(jdbc 访问 hive)、WEBUI(浏览器访问 hive)
2)元数据:Metastore
元数据包括:表名、表所属的数据库(默认是 default)、表的拥有者、列/分区字段、 表的类型(是否是外部表)、表的数据所在目录等;
默认存储在自带的 derby 数据库中,推荐使用 MySQL 存储 Metastore
3)Hadoop
使用 HDFS 进行存储,使用 MapReduce 进行计算。
4)驱动器:Driver
(1)解析器(SQL Parser):将 SQL 字符串转换成抽象语法树 AST,这一步一般都用第 三方工具库完成,比如 antlr;对 AST 进行语法析,比如表是否存在、字段是否存在、SQL 语义是否有误。
(2)编译器(Physical Plan):将 AST 编译生成逻辑执行计划。
(3)优化器(Query Optimizer):对逻辑执行计划进行优化。
(4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于 Hive 来 说,就是 MR/Spark。
image.png
Hive 通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的 Driver, 结合元数据(MetaStore),将这些指令翻译成 MapReduce,提交到 Hadoop 中执行,最后,将 执行返回的结果输出到用户交互接口。

第 2 章 Hive 安装

官网 文档查看地址 下载地址 github地址

2.2Hive 安装部署

1)把 apache-hive-3.1.2-bin.tar.gz 上传到 linux 的/opt/software 目录下
2)解压 apache-hive-3.1.2-bin.tar.gz 到/opt/module/目录下面

  1. [atguigu@hadoop102 software]$ tar -zxvf /opt/software/apache-hive-3.1.2-bin.tar.gz -C /opt/module/

3)修改 apache-hive-3.1.2-bin.tar.gz 的名称为 hive

  1. [atguigu@hadoop102 software]$ mv /opt/module/apache-hive-3.1.2-bin/ /opt/module/hive

4)修改/etc/profile.d/my_env.sh,添加环境变量

  1. [atguigu@hadoop102 software]$ sudo vim /etc/profile.d/my_env.sh

5)添加内容

  1. #HIVE_HOME
  2. export HIVE_HOME=/opt/module/hive
  3. export PATH=$PATH:$HIVE_HOME/bin

6)解决日志 Jar 包冲突

  1. [atguigu@hadoop102 software]$ mv $HIVE_HOME/lib/log4j-slf4j-impl-2.10.0.jar $HIVE_HOME/lib/log4j-slf4j-impl-2.10.0.bak

7)初始化元数据库

  1. [atguigu@hadoop102 hive]$ bin/schematool -dbType derby -initSchema

2.2.2 启动并使用 Hive

1)启动 Hive

  1. [atguigu@hadoop102 hive]$ bin/hive

2)使用 Hive

  1. hive> show databases;
  2. hive> show tables;
  3. hive> create table test(id int);
  4. hive> insert into test values(1);
  5. hive> select * from test;

3)在 CRT 窗口中开启另一个窗口开启 Hive,在/tmp/atguigu 目录下监控 hive.log 文件

  1. Caused by: ERROR XSDB6: Another instance of Derby may have already booted
  2. the database /opt/module/hive/metastore_db.
  3. at
  4. org.apache.derby.iapi.error.StandardException.newException(Unknown
  5. Source)
  6. at
  7. org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
  8. at
  9. org.apache.derby.impl.store.raw.data.BaseDataFileFactory.privGetJBMSLockO
  10. nDB(Unknown Source)
  11. at
  12. org.apache.derby.impl.store.raw.data.BaseDataFileFactory.run(Unknown
  13. Source)
  14. ...

原因在于 Hive 默认使用的元数据库为 derby,开启 Hive 之后就会占用元数据库,且不与 其他客户端共享数据,所以我们需要将 Hive 的元数据地址改为 MySQL。

2.3MySQL 安装

参考地址

2.4 Hive 元数据配置到 MySQL

2.4.1 拷贝驱动

将 MySQL 的 JDBC 驱动拷贝到 Hive 的 lib 目录下

  1. [atguigu@hadoop102 software]$ cp /opt/software/mysql-connector-java-5.1.37.jar $HIVE_HOME/lib

2.4.2 配置 Metastore 到 MySQL

1)在$HIVE_HOME/conf 目录下新建 hive-site.xml 文件

  1. [atguigu@hadoop102 software]$ vim $HIVE_HOME/conf/hive-site.xml

添加如下内容

  1. <?xml version="1.0"?>
  2. <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
  3. <configuration>
  4. <!-- jdbc 连接的 URL -->
  5. <property>
  6. <name>javax.jdo.option.ConnectionURL</name>
  7. <value>jdbc:mysql://hadoop102:3306/metastore?useSSL=false</value>
  8. </property>
  9. <!-- jdbc 连接的 Driver-->
  10. <property>
  11. <name>javax.jdo.option.ConnectionDriverName</name>
  12. <value>com.mysql.jdbc.Driver</value>
  13. </property>
  14. <!-- jdbc 连接的 username-->
  15. <property>
  16. <name>javax.jdo.option.ConnectionUserName</name>
  17. <value>root</value>
  18. </property>
  19. <!-- jdbc 连接的 password -->
  20. <property>
  21. <name>javax.jdo.option.ConnectionPassword</name>
  22. <value>000000</value>
  23. </property>
  24. <!-- Hive 元数据存储版本的验证 -->
  25. <property>
  26. <name>hive.metastore.schema.verification</name>
  27. <value>false</value>
  28. </property>
  29. <!--元数据存储授权-->
  30. <property>
  31. <name>hive.metastore.event.db.notification.api.auth</name>
  32. <value>false</value>
  33. </property>
  34. <!-- Hive 默认在 HDFS 的工作目录 -->
  35. <property>
  36. <name>hive.metastore.warehouse.dir</name>
  37. <value>/user/hive/warehouse</value>
  38. </property>
  39. </configuration>

2)登陆 MySQL

  1. [atguigu@hadoop102 software]$ mysql -uroot -p000000

3)新建 Hive 元数据库

  1. mysql> create database metastore;
  2. mysql> quit;

4) 初始化 Hive 元数据库

  1. [atguigu@hadoop102 software]$ schematool -initSchema -dbType mysql - verbose

2.4.3 再次启动 Hive

1)启动 Hive

  1. [atguigu@hadoop102 hive]$ bin/hive

2)使用 Hive

  1. hive> show databases;
  2. hive> show tables;
  3. hive> create table test (id int);
  4. hive> insert into test values(1);
  5. hive> select * from test;

3)在 CRT 窗口中开启另一个窗口开启 Hive

  1. hive> show databases;
  2. hive> show tables;
  3. hive> select * from aa;

2.5 使用元数据服务的方式访问 Hive

1)在 hive-site.xml 文件中添加如下配置信息

  1. <!-- 指定存储元数据要连接的地址 -->
  2. <property>
  3. <name>hive.metastore.uris</name>
  4. <value>thrift://hadoop102:9083</value>
  5. </property>

2)启动 metastore

  1. [atguigu@hadoop202 hive]$ hive --service metastore
  2. 2020-04-24 16:58:08: Starting Hive Metastore Server
  3. 注意: 启动后窗口不能再操作,需打开一个新的 shell 窗口做别的操作

3)启动 hive

  1. [atguigu@hadoop202 hive]$ bin/hive

2.6 使用 JDBC 方式访问 Hive

1)在 hive-site.xml 文件中添加如下配置信息

  1. <!-- 指定 hiveserver2 连接的 host -->
  2. <property>
  3. <name>hive.server2.thrift.bind.host</name>
  4. <value>hadoop102</value>
  5. </property>
  6. <!-- 指定 hiveserver2 连接的端口号 -->
  7. <property>
  8. <name>hive.server2.thrift.port</name>
  9. <value>10000</value>
  10. </property>

2)启动 hiveserver2

  1. [atguigu@hadoop102 hive]$ bin/hive --service hiveserver2

3)启动 beeline 客户端(需要多等待一会)

  1. [atguigu@hadoop102 hive]$ bin/beeline -u jdbc:hive2://hadoop102:10000 -n why

java.sql.SQLException: Could not open client transport with JDBC Uri: jdbc:hive2://localhost:10000/default: java.net.ConnectException: 拒绝连接
通过sudo netstat -anp|grep 10000 查看谁占用了10000端口,也就是hiveserver2有没有启动。
hiveserver2 会显示七八个Hive Session ID之后,才会真正启动,这要等个几分钟呢。在sudo netstat -anp|grep 10000能查到端口前,都证明hiveserver2没有启动
image.png
解决方案:
在hadoop的配置文件core-site.xml增加如下配置,重启hdfs,其中“xxx”是连接beeline的用户,将“xxx”替换成自己的用户名即可。最关键的是一定要重启hadoop,先stop-all.sh,再start-all.sh,否则不会生效的!!那样就还是报错!

  1. <property>
  2. <name>hadoop.proxyuser.xxx.hosts</name>
  3. <value>*</value>
  4. </property>
  5. <property>
  6. <name>hadoop.proxyuser.xxx.groups</name>
  7. <value>*</value>
  8. </property>

bug解决参考地址
4)看到如下界面

  1. Connecting to jdbc:hive2://hadoop102:10000
  2. Connected to: Apache Hive (version 3.1.2)
  3. Driver: Hive JDBC (version 3.1.2)
  4. Transaction isolation: TRANSACTION_REPEATABLE_READ
  5. Beeline version 3.1.2 by Apache Hive
  6. 0: jdbc:hive2://hadoop102:10000>

5)编写 hive 服务启动脚本(了解)
(1) 前台启动的方式导致需要打开多个 shell 窗口,可以使用如下方式后台方式启动
nohup: 放在命令开头,表示不挂起,也就是关闭终端进程也继续保持运行状态
/dev/null:是 Linux 文件系统中的一个文件,被称为黑洞,所有写入改文件的内容 都会被自动丢弃
2>&1 : 表示将错误重定向到标准输出上
&: 放在命令结尾,表示后台运行
一般会组合使用: nohup [xxx 命令操作]> file 2>&1 &,表示将 xxx 命令运行的结 果输出到 file 中,并保持命令启动的进程在后台运行。
如上命令不要求掌握。

  1. [atguigu@hadoop202 hive]$ nohup hive --service metastore 2>&1 &
  2. [atguigu@hadoop202 hive]$ nohup hive --service hiveserver2 2>&1 &

(2) 为了方便使用,可以直接编写脚本来管理服务的启动和关闭

  1. [atguigu@hadoop102 hive]$ vim $HIVE_HOME/bin/hiveservices.sh

内容如下:此脚本的编写不要求掌握。直接拿来使用即可。

  1. #!/bin/bash
  2. HIVE_LOG_DIR=$HIVE_HOME/logs
  3. if [ ! -d $HIVE_LOG_DIR ]
  4. then
  5. mkdir -p $HIVE_LOG_DIR
  6. fi#检查进程是否运行正常,参数 1 为进程名,参数 2 为进程端口
  7. function check_process()
  8. {
  9. pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print
  10. $2}')
  11. ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -
  12. d '/' -f 1)
  13. echo $pid
  14. [[ "$pid" =~ "$ppid" ]] && [ "$ppid" ] && return 0 || return 1
  15. }
  16. function hive_start()
  17. {
  18. metapid=$(check_process HiveMetastore 9083)
  19. cmd="nohup hive --service metastore >$HIVE_LOG_DIR/metastore.log 2>&1
  20. &"
  21. [ -z "$metapid" ] && eval $cmd || echo "Metastroe 服务已启动"
  22. server2pid=$(check_process HiveServer2 10000)
  23. cmd="nohup hiveserver2 >$HIVE_LOG_DIR/hiveServer2.log 2>&1 &"
  24. [ -z "$server2pid" ] && eval $cmd || echo "HiveServer2 服务已启动" }
  25. function hive_stop()
  26. {
  27. metapid=$(check_process HiveMetastore 9083)
  28. [ "$metapid" ] && kill $metapid || echo "Metastore 服务未启动"
  29. server2pid=$(check_process HiveServer2 10000)
  30. [ "$server2pid" ] && kill $server2pid || echo "HiveServer2 服务未启动" }
  31. case $1 in
  32. "start")
  33. hive_start
  34. ;;
  35. "stop")
  36. hive_stop
  37. ;;
  38. "restart")
  39. hive_stop
  40. sleep 2
  41. hive_start
  42. ;;
  43. "status")
  44. check_process HiveMetastore 9083 >/dev/null && echo "Metastore 服务运行
  45. 正常" || echo "Metastore 服务运行异常"
  46. check_process HiveServer2 10000 >/dev/null && echo "HiveServer2 服务运
  47. 行正常" || echo "HiveServer2 服务运行异常"
  48. ;;
  49. *)
  50. echo Invalid Args!
  51. echo 'Usage: '$(basename $0)' start|stop|restart|status'
  52. ;;
  53. esac

3)添加执行权限

  1. [atguigu@hadoop102 hive]$ chmod +x $HIVE_HOME/bin/hiveservices.sh

4)启动 Hive 后台服务

  1. [atguigu@hadoop102 hive]$ hiveservices.sh start

2.7 Hive 常用交互命令

  1. [atguigu@hadoop102 hive]$ bin/hive -help
  2. usage: hive
  3. -d,--define <key=value> Variable subsitution to apply to hive
  4. commands. e.g. -d A=B or --define A=B
  5. --database <databasename> Specify the database to use
  6. -e <quoted-query-string> SQL from command line
  7. -f <filename> SQL from files
  8. -H,--help Print help information
  9. --hiveconf <property=value> Use value for given property
  10. --hivevar <key=value> Variable subsitution to apply to hive
  11. commands. e.g. --hivevar A=B
  12. -i <filename> Initialization SQL file
  13. -S,--silent Silent mode in interactive shell
  14. -v,--verbose Verbose mode (echo executed SQL to the
  15. console)

1)“-e”不进入 hive 的交互窗口执行 sql 语句

  1. [atguigu@hadoop102 hive]$ bin/hive -e "select id from student;"

2)“-f”执行脚本中 sql 语句

  1. 1)在/opt/module/hive/下创建 datas 目录并在 datas 目录下创建 hivef.sql 文件
  2. [atguigu@hadoop102 datas]$ touch hivef.sql
  3. 2)文件中写入正确的 sql 语句
  4. select *from student;
  5. 3)执行文件中的 sql 语句
  6. [atguigu@hadoop102 hive]$ bin/hive -f /opt/module/hive/datas/hivef.sql
  7. 4)执行文件中的 sql 语句并将结果写入文件中
  8. [atguigu@hadoop102 hive]$ bin/hive -f /opt/module/hive/datas/hivef.sql >
  9. /opt/module/datas/hive_result.txt

2.8 Hive 其他命令操作
1)退出 hive 窗口:
hive(default)>exit;
hive(default)>quit;
2)在 hive cli 命令窗口中如何查看 hdfs 文件系统
hive(default)>dfs -ls /;
3)查看在 hive 中输入的所有历史命令
(1)进入到当前用户的根目录 /root 或/home/atguigu
(2)查看. hivehistory 文件
[atguig2u@hadoop102 ~]$ cat .hivehistory