hive(1) : 基础入门就这么简单

1,070 阅读12分钟

这是我参与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作为资源调度。

image-20210712195256896

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,可以多开几个客户端窗口。

image-20210712195311575

  • 用户接口: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。

image-20210712195443745

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 安装地址

2.2 Mysql 安装

hive 需要借助 mysql 来存储 metadata 元数据,所以需要安装 mysql 并配置 mysql。

mysql 的安装之前写过两篇文章了,分别是 rpm 安装和源码安装。

juejin.cn/post/688635…

juejin.cn/post/688855…

但下面,我将用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

image-20210712202715973

登录并更改密码:注意-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…

    image-20210712222404918

  • 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
    

    image-20210712224653098

完成之后,我们可与发现这个数据库中多出了很多张表。

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 语句

      1. 创建hive.sql ,在里面编写sql 文件
      1. 执行文件中的 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 目录下(当前用户名下)

    image-20210714223430697

  • 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相关的设定,必须用前两种方式设定,因为那些参数的读取在会话建立以前已经完成了