Hive入门

一、Hive 基本概念

1.1 什么是 Hive

Apache Hive是一款建立在Hadoop之上的开源数据仓库系统,可以将存储在Hadoop文件中的结构化、半结构化数据文件映射为一张数据库表,基于表提供了一种类似SQL的查询模型,称为Hive查询语言(HQL),用于访问和分析存储在Hadoop文件中的大型数据集。

Hive核心是将HQL转换为MapReduce(Spark),然后将程序提交到Hadoop群集执行。Hive由Facebook实现并开源。

img

1.2 为什么使用Hive

使用Hadoop MapReduce直接处理数据所面临的问题

  • 人员学习成本太高 需要掌握java语言
  • MapReduce实现复杂查询逻辑开发难度太大

使用Hive处理数据的好处

  • 操作接口采用类SQL语法,提供快速开发的能力(简单、容易上手)
  • 避免直接写MapReduce,减少开发人员的学习成本
  • 支持自定义函数,功能扩展很方便
  • 背靠Hadoop,擅长存储分析海量数据集

1.3 Hive与Hadoop的关系

从功能来说,数据仓库软件,至少需要具备下述两种能力:

  • 存储数据的能力
  • 分析数据的能力

Apache Hive作为一款大数据时代的数据仓库软件,当然也具备上述两种能力。只不过Hive并不是自己实现了上述两种能力,而是借助Hadoop。

Hive利用HDFS存储数据,利用MapReduce查询分析数据。

这样突然发现Hive没啥用,不过是套壳Hadoop罢了。其实不然,Hive的最大的魅力在于用户专注于编写HQL,Hive帮您转换成为MapReduce程序完成对数据的分析。

img

1.4 Hive与Mysql

Hive虽然具有RDBMS数据库的外表,包括数据模型、SQL语法都十分相似,但应用场景却完全不同。Hive只适合用来做海量数据的离线分析。Hive的定位是数据仓库,面向分析的OLAP系统。
因此时刻告诉自己,Hive不是大型数据库,也不是要取代Mysql承担业务数据处理。
更直观的对比请看下面这幅图:

img

1.5 场景设计

场景需求

在HDFS文件系统上有一个文件,路径为/data/china_user.txt,其内容如下:

1,zhangsan,18,beijing
2,lisi,25,shanghai
3,allen,30,shanghai
4,wangwu,15,nanjing
5,james,45,hangzhou
6,tony,26,beijing

需求:统计来自于上海年龄大于25岁的用户有多少个?

如果让您设计Hive这款软件,要求能够实现用户编写sql语句,Hive自动将sql转换MapReduce程序,处理位于HDFS上的结构化数据。如何实现?

场景目的

重点理解下面两点:

Hive能将数据文件映射成为一张表,这个映射是指什么

Hive软件本身到底承担了什么功能职责?

功能实现关键

映射信息记录

映射在数学上称之为一种对应关系,比如y=x+1,对于每一个x的值都有与之对应的y的值。在hive中能够写sql处理的前提是针对表,而不是针对文件,因此需要将文件和表之间的对应关系描述记录清楚。

映射信息专业的叫法称之为元数据信息(元数据是指用来描述数据的数据 metadata)。

img

具体来看,要记录的元数据信息包括

  • 表对应着哪个文件(位置信息)
  • 表的列对应着文件哪一个字段(顺序信息)
  • 文件字段之间的分隔符是什么

Sql语法解析、编译

用户写完sql之后,hive需要针对sql进行语法校验,并且根据记录的元数据信息解读sql背后的含义,制定执行计划。并且把执行计划转换成MapReduce程序来执行,把执行的结果封装返回给用户。

最终效果

基于上述分析,最终要想模拟实现的Hive的功能,大致需要下图所示组件参与其中,从中可以感受一下Hive承担了什么职责。

img

当然,也可以把这个理解为hive的架构图。

二、Hive架构、组件

2.1 Hive架构图

img

2.2 Hive组件

用户接口:包括 CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命令行;Hive中的Thrift服务器允许外部客户端通过网络与Hive进行交互,类似于JDBC或ODBC协议。WebGUI是通过浏览器访问Hive。

元数据存储:通常是存储在关系数据库如 mysql/derby中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。

Driver驱动程序,包括语法解析器、计划编译器、优化器、执行器:完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有执行引擎调用执行。

执行引擎:Hive本身并不直接处理数据文件。而是通过执行引擎处理。当下Hive支持MapReduce、Tez、Spark3种执行引擎。

三、Hive数据模型

数据模型:用来描述数据、组织数据和对数据进行操作,是对现实世界数据特征的描述。Hive的数据模型类似于RDBMS库表结构,此外还有自己特有模型。
Hive中的数据可以在粒度级别上分为三类:

  • Table 表
  • Partition分区
  • Bucket 分桶

img

3.1 Databases

Hive作为一个数据仓库,在结构上积极向传统数据库看齐,也分数据库(Schema),每个数据库下面有各自的表组成。默认数据库default。

Hive的数据都是存储在HDFS上的,默认有一个根目录,在hive-site.xml中,由参数hive.metastore.warehouse.dir指定。默认值为/user/hive/warehouse。

因此,Hive中的数据库在HDFS上的存储路径为:${hive.metastore.warehouse.dir}/databasename.db

比如,名为itcast的数据库存储路径为:/user/hive/warehouse/itcast.db

3.2 Tables

Hive表与关系数据库中的表相同。Hive中的表所对应的数据是存储在Hadoop的文件系统中,而表相关的元数据是存储在RDBMS中。
在Hadoop中,数据通常驻留在HDFS中,尽管它可以驻留在任何Hadoop文件系统中,包括本地文件系统或S3。Hive有两种类型的表:

  • Managed Table内部表、托管表
  • External Table外部表

创建表时,默是内部表。关于内部表和外部表的区别,我们后续知识点再做展开探讨。Hive中的表的数据在HDFS上的存储路径为:${hive.metastore.warehouse.dir}/databasename.db/tablename

比如,itcast的数据库下t_user表存储路径为:/user/hive/warehouse/itcast.db/t_user
img

3.3 Partitions

Partition分区是hive的一种优化手段表。分区是指根据分区列(例如“日期day”)的值将表划分为不同分区。这样可以更快地对指定分区数据进行查询。

分区在存储层面上的表现是:table表目录下以子文件夹形式存在。

一个文件夹表示一个分区。子文件命名标准:分区列=分区值

Hive还支持分区下继续创建分区,所谓的多重分区。关于分区表的使用和详细介绍,后面模块会单独展开详细讲解。
img

3.4 Buckets

Bucket分桶表是hive的一种优化手段表。分桶是指根据表中字段(例如“编号ID”)的值,经过hash计算规则将数据文件划分成指定的若干个小文件。
img

分桶规则:hashfunc(ID) % 桶个数,余数相同的分到同一个文件。

分桶的好处是可以优化join查询和方便抽样查询。Bucket分桶表在hdfs中表现为同一个表目录下数据根据hash散列之后变成多个文件。关于桶表以及分桶操作,后面模块会单独展开详细讲解。
img

四、Hive 安装

4.1 元数据相关名词

Metadata

Metadata即元数据。元数据包含用Hive创建的database、table、表的位置、类型、属性,字段顺序类型等元信息。元数据存储在关系型数据库中。如hive内置的Derby、或者第三方如MySQL等。

Metastore

Metastore即元数据服务。Metastore服务的作用是管理metadata元数据,对外暴露服务地址,让各种客户端通过连接metastore服务,由metastore再去连接MySQL数据库来存取元数据。

有了metastore服务,就可以有多个客户端同时连接,而且这些客户端不需要知道MySQL数据库的用户名和密码,只需要连接metastore 服务即可。某种程度上也保证了hive元数据的安全。

img

4.2 metastore三种配置方式

metastore服务配置有3种模式:内嵌模式本地模式远程模式。区分3种配置方式的关键是弄清楚两个问题:

  • Metastore服务是否需要单独配置、单独启动?
  • Metadata是存储在内置的derby中,还是第三方RDBMS,比如Mysql。

img

内嵌模式

内嵌模式(Embedded Metastore)是metastore默认部署模式。此种模式下,元数据存储在内置的Derby数据库,并且Derby数据库和metastore服务都嵌入在主HiveServer进程中,当启动HiveServer进程时,Derby和metastore都会启动。不需要额外起Metastore服务。

但是一次只能支持一个活动用户,适用于测试体验,不适用于生产环境。

img

本地模式

本地模式(Local Metastore)下,Hive Metastore服务与主HiveServer进程在同一进程中运行,但是存储元数据的数据库在单独的进程中运行,并且可以在单独的主机上。metastore服务将通过JDBC与metastore数据库进行通信。
本地模式采用外部数据库来存储元数据,推荐使用MySQL。

hive根据hive.metastore.uris 参数值来判断,如果为空,则为本地模式。
缺点是:每启动一次hive服务,都内置启动了一个metastore。

img

远程模式

远程模式(Remote Metastore)下,Metastore服务在其自己的单独JVM上运行,而不在HiveServer的JVM中运行。如果其他进程希望与Metastore服务器通信,则可以使用Thrift Network API进行通信。

生产环境中,建议用远程模式来配置Hive Metastore。在这种情况下,其他依赖hive的软件都可以通过Metastore访问hive。由于还可以完全屏蔽数据库层,因此这也带来了更好的可管理性/安全性。

远程模式下,需要配置hive.metastore.uris 参数来指定metastore服务运行的机器ip和端口,并且需要单独手动启动metastore服务。
img

4.3 Mysql的安装

相关mysql和jar
链接:https://pan.baidu.com/s/1Y76xSBscsB9_qQa1gwXLVA
提取码:lqi4

1)检查当前系统是否安装过Mysql

[atguigu@hadoop102 ~]$ rpm -qa|grep mariadb
mariadb-libs-5.5.56-2.el7.x86_64 //如果存在通过如下命令卸载
[atguigu @hadoop102 ~]$ sudo rpm -e --nodeps  mariadb-libs   //用此命令卸载mariadb

2)将MySQL安装包拷贝到/opt/software/mysql-lib目录下

3)解压MySQL安装包

//解压*.tar包,参数只需要-xf;            解压*.tar.gz,参数:-zxvf
[atguigu @hadoop102 mysql-lib]$ tar -xf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar -C

4)在安装目录下执行rpm安装, 要以下按照顺序依次执行

[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
[atguigu @hadoop102 mysql-lib]$ sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm

如果Linux是最小化安装的,在安装mysql-community-server-5.7.28-1.el7.x86_64.rpm时可能会出现如下错误:

[atguigu@hadoop102 software]$ sudo rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
警告:mysql-community-server-5.7.28-1.el7.x86_64.rpm: 头V3 DSA/SHA1 Signature, 密钥 ID 5072e1f5: NOKEY
错误:依赖检测失败:
        libaio.so.1()(64bit) 被 mysql-community-server-5.7.28-1.el7.x86_64 需要
        libaio.so.1(LIBAIO_0.1)(64bit) 被 mysql-community-server-5.7.28-1.el7.x86_64 需要
        libaio.so.1(LIBAIO_0.4)(64bit) 被 mysql-community-server-5.7.28-1.el7.x86_64 需要

通过yum安装缺少的依赖,然后重新安装mysql-community-server-5.7.28-1.el7.x86_64 即可

[atguigu@hadoop102 mysql-lib] yum install -y libaio

5)删除/etc/my.cnf文件中datadir指向的目录下的所有内容,如果有内容的情况下需要删除

查看datadir的值

datadir=/var/lib/mysql

[atguigu@hadoop102 mysql-lib]$ vim /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql

删除/var/lib/mysql目录下的所有内容:

[atguigu @hadoop102 mysql]# cd /var/lib/mysql
[atguigu @hadoop102 mysql]# sudo rm -rf ./*  //注意执行命令的位置

6)初始化数据库

[atguigu @hadoop102 opt]$ sudo mysqld --initialize --user=mysql

7)查看临时生成的root用户的密码

[atguigu @hadoop102 opt]$ sudo cat /var/log/mysqld.log 

img

8)启动mysql服务

[atguigu @hadoop102 opt]$ sudo systemctl start mysqld

9)登录mysql数据库

[atguigu @hadoop102 opt]$ mysql -uroot -p
Enter password:   输入临时生成的密码

必须先修改root用户的密码,否则执行其他的操作会报错, 记住自己设置的密码

mysql> set password = password("123456");

10)修改mysql库下的user表中的root用户允许任意ip连接,可以客户端远程登录

mysql> update mysql.user set host='%' where user='root';

mysql> flush privileges;

11)通过navicat远程登录验证

img

4.4 Hive 安装地址

1)Hive 官网地址
http://hive.apache.org/
2)文档查看地址
https://cwiki.apache.org/confluence/display/Hive/GettingStarted
3)下载地址
http://archive.apache.org/dist/hive/
4)github 地址
https://github.com/apache/hive

4.5 Hive 安装部署

安装 Hive

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

[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

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

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

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

5)添加内容

#HIVE_HOME
export HIVE_HOME=/opt/module/hive
export PATH=$PATH:$HIVE_HOME/bin

source一下

source /etc/profile

6)解决日志 Jar 包冲突

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

Hive的元数据配置到Mysql

1)拷贝驱动

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

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

2)配置Metastore到MySql

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

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

添加如下内容

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <!-- jdbc连接的URL,metastore:存储元数据的mysql的库 -->
    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value>jdbc:mysql://hadoop102:3306/metastore?useSSL=false</value>
    </property>

    <!-- jdbc连接的Driver-->
    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.jdbc.Driver</value>
    </property>

    <!-- jdbc连接的登录Mysql的username-->
    <property>
        <name>javax.jdo.option.ConnectionUserName</name>
        <value>root</value>
    </property>

    <!-- jdbc连接的登录Mysql的password -->
    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>123456</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://hadoop102: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>hadoop102</value>
    </property>
    <!-- 元数据存储授权  -->
    <property>
        <name>hive.metastore.event.db.notification.api.auth</name>
        <value>false</value>
    </property>

</configuration>

注意:主机ip,mysql登录的用户密码不要配错了

Hive的启动

1)初始化元数据库

登录Mysql

[atguigu@hadoop102 software]$ mysql -uroot -p123456

创建Hive的元数据库,然后退出

mysql> create database metastore;
mysql> quit;

初始化Hive元数据库

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

2)启动metastore和hiveserver2

Hive 2.x以上版本,要先启动这两个服务,否则会报错

FAILED: HiveException java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

(1)启动metastore

[atguigu@hadoop202 hive]$ hive --service metastore 
2021-11-24 16:58:08: Starting Hive Metastore Server  

注意: 启动后窗口不能再操作,需打开一个新的shell窗口做别的操作

(2)启动 hiveserver2

[atguigu@hadoop202 hive]$ hive --service hiveserver2
which: no hbase in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/module/jdk1.8.0_212/bin:/opt/module/hadoop-3.1.3/bin:/opt/module/hadoop-3.1.3/sbin:/opt/module/hive/bin:/home/atguigu/.local/bin:/home/atguigu/bin)
2021-11-24 17:00:19: Starting HiveServer2  

注意: 启动后窗口不能再操作,需打开一个新的shell窗口做别的操作

3)编写hive服务启动脚本

由于前台启动的方式导致需要打开多个shell窗口,过于复杂,可以使用通过nohup后台启动
nohup: 放在命令开头,表示不挂起,也就是关闭终端进程也继续保持运行状态

2>&1 : 表示将错误重定向到标准输出上

&: 放在命令结尾,表示后台运行

一般会组合使用: nohup [xxx命令操作]> file 2>&1 & , 表示将xxx命令运行的结果输出到file中,并保持命令启动的进程在后台运行。

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

编写脚本

创建脚本myhive.sh

[atguigu@hadoop102 hive]$ vim $HIVE_HOME/bin/myhive.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

添加执行权限

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

启动Hive后台服务(需先启动hadoop)

[atguigu@hadoop102 hive]$ myhive.sh start

等一会查看hive启动状态:myhive.sh status

4.6 Hive客户端使用

Hive Client、Hive Beeline Client

Hive发展至今,总共历经了两代客户端工具。

第一代客户端(deprecated不推荐使用):$HIVE_HOME/bin/hive, 是一个 shellUtil。主要功能:一是可用于以交互或批处理模式运行Hive查询;二是用于Hive相关服务的启动,比如metastore服务。

第二代客户端(recommended 推荐使用):$HIVE_HOME/bin/beeline,是一个JDBC客户端,是官方强烈推荐使用的Hive命令行工具,和第一代客户端相比,性能加强安全性提高

Beeline Shell在嵌入式模式和远程模式下均可工作。在嵌入式模式下,它运行嵌入式 Hive(类似于Hive Client),而远程模式下beeline通过 Thrift 连接到单独的 HiveServer2 服务上,这也是官方推荐在生产环境中使用的模式。
那么问题来了,HiveServer2是什么?HiveServer1哪里去了?
img

HiveServer、HiveServer2服务

HiveServer、HiveServer2都是Hive自带的两种服务,允许客户端在不启动CLI的情况下对Hive中的数据进行操作,且两个都允许远程客户端使用多种编程语言如java,python等向hive提交请求,取回结果。

但是,HiveServer不能处理多于一个客户端的并发请求。因此在Hive-0.11.0版本中重写了HiveServer代码得到了HiveServer2,进而解决了该问题。HiveServer已经被废弃。

HiveServer2支持多客户端的并发和身份认证,旨在为开放API客户端如JDBC、ODBC提供更好的支持。

Hive服务和客户端关系梳理

HiveServer2通过Metastore服务读写元数据。所以在远程模式下,启动HiveServer2之前必须先首先启动metastore服务。
特别注意:远程模式下,Beeline客户端只能通过HiveServer2服务访问Hive。而Hive Client是通过Metastore服务访问的。具体关系如下:

img

1)通过hive自带的beeline客户端访问

在启动hive后,使用JDBC的方式访问hive

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

看到如下界面

Connecting to jdbc:hive2://hadoop102:10000
Connected to: Apache Hive (version 3.1.2)
Driver: Hive JDBC (version 3.1.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 3.1.2 by Apache Hive0: jdbc:hive2://hadoop102:10000>

如果这里出问题了,参考:https://blog.csdn.net/u011495642/article/details/84305944

原因可能是在hadoop的core.site.xml缺少代理对象设置。

主要原因是hadoop引入了一个安全伪装机制,使得hadoop 不允许上层系统直接将实际用户传递到hadoop层,而是将实际用户传递给一个超级代理,由此代理在hadoop上执行操作,避免任意客户端随意操作hadoop。

2)hive脚本访问

[atguigu@hadoop202 hive]$ bin/hive 

五、Hive参数配置

5.1 CLIs and Commands客户端和命令

Hive CLI

$HIVE_HOME/bin/hive是一个shellUtil,通常称之为hive的第一代客户端或者旧客户端,主要功能有两个:

  • 一:用于以交互式批处理模式运行Hive查询,注意,此时作为客户端,需要并且能够访问的是Hive metastore服务,而不是hiveserver2服务。
  • 二:用于hive相关服务的启动,比如metastore服务。

可以通过运行"hive -H" 或者 "hive --help"来查看命令行选项。

img

Batch Mode 批处理模式

当使用-e或-f选项运行$ HIVE_HOME / bin / hive时,它将以批处理模式执行SQL命令。所谓的批处理可以理解为一次性执行,执行完毕退出

#-e
$HIVE_HOME/bin/hive -e 'show databases'

#-f
cd ~
#编辑一个sql文件 里面写上合法正确的sql语句
vim hive.sql
show databases;
#执行 从客户端所在机器的本地磁盘加载文件
$HIVE_HOME/bin/hive -f /root/hive.sql
#也可以从其他文件系统加载sql文件执行
$HIVE_HOME/bin/hive -f hdfs://<namenode>:<port>/hive-script.sql
$HIVE_HOME/bin/hive -f s3://mys3bucket/s3-script.sql
#使用静默模式将数据从查询中转储到文件中
$HIVE_HOME/bin/hive -S -e 'select * from itheima.student' > a.txt

Interactive Shell 交互式模式

所谓交互式模式可以理解为客户端和hive服务一直保持连接,除非手动退出客户端。

/export/server/hive/bin/hive

hive> show databases;
OK
default
itcast
itheima
Time taken: 0.028 seconds, Fetched: 3 row(s)

hive> use itcast;
OK
Time taken: 0.027 seconds

hive> exit;

启动服务、修改配置

远程模式部署方式下,hive metastore服务需要单独配置手动启动,此时就可以使用Hive CLI来进行相关服务的启动,hiveserver2服务类似。

#--service
$HIVE_HOME/bin/hive --service metastore
$HIVE_HOME/bin/hive --service hiveserver2

#--hiveconf
$HIVE_HOME/bin/hive --hiveconf hive.root.logger=DEBUG,console

Beeline CLI

$HIVE_HOME/bin/beeline被称之为第二代客户端或者新客户端,是一个JDBC客户端,是官方强烈推荐使用的Hive命令行工具,和第一代客户端相比,性能加强安全性提高。Beeline在嵌入式模式和远程模式下均可工作。

在嵌入式模式下,它运行嵌入式Hive(类似于Hive CLI);

远程模式下beeline通过Thrift连接到单独的HiveServer2服务上,这也是官方推荐在生产环境中使用的模式。

常见的使用方式如下所示,在启动hiveserver2服务的前提下使用beeline远程连接:

[root@node3 ~]# /export/server/hive/bin/beeline
Beeline version 3.1.2 by Apache Hive
beeline> ! connect jdbc:hive2://node1:10000
Connecting to jdbc:hive2://node1:10000
Enter username for jdbc:hive2://node1:10000: root
Enter password for jdbc:hive2://node1:10000:
Connected to: Apache Hive (version 3.1.2)
Driver: Hive JDBC (version 3.1.2)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://node1:10000>

beeline支持的参数非常多,可以通过官方文档进行查询
https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-Beeline%E2%80%93NewCommandLineShell

5.2 Configuration Properties配置属性

配置属性概述

Hive作为一款复杂的数据仓库软件,除了一些默认的属性行为之外,还支持用户配置属性进行修改,使得在某些场景下满足用户的需求。
作为用户我们需要掌握两件事:

  • 一是:Hive有哪些属性支持修改,修改了有什么功能;
  • 二是:Hive支持哪种方式进行修改,修改是临时生效还是永久生效的。

Hive配置属性的规范列表是在HiveConf.Java类中管理的,因此请参考该HiveConf.java文件,以获取Hive当前使用的发行版中可用的配置属性的完整列表。从Hive 0.14.0开始,会从HiveConf.java类中直接生成配置模板文件hive-default.xml.template,它是当前版本配置及其默认值的可靠来源。

详细的配置参数大全可以参考Hive官网配置参数,在页面使用ctrl+f进行搜索。

https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties
img

修改配置属性方式

方式1:hive-site.xml配置文件

在$HIVE_HOME/conf路径下,可以添加一个hive-site.xml文件,把需要定义修改的配置属性添加进去,这个配置文件会影响到这个Hive安装包的任何一种服务启动、客户端使用方式,可以理解为是Hive的全局配置。
比如我们指定使用MySQL作为Hive元数据的存储介质,那么就需要把Hive连接MySQL的相关属性配置在hive-site.xml文件中,这样不管是本地模式还是远程模式启动,不管客户端本地连接还是远程连接,都将访问同一个元数据存储介质,大家使用的元数据都是一致的。

    <!-- 存储元数据mysql相关配置 -->
    <property>
        <name>javax.jdo.option.ConnectionURL</name>
        <value> jdbc:mysql://node1:3306/hive?createDatabaseIfNotExist=true&amp;useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8</value>
    </property>

    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.jdbc.Driver</value>
    </property>

    <property>
        <name>javax.jdo.option.ConnectionUserName</name>
        <value>root</value>
    </property>

    <property>
        <name>javax.jdo.option.ConnectionPassword</name>
        <value>hadoop</value>
    </property>
</configuration>

方式2:hiveconf命令行参数

hiveconf是一个命令行的参数,用于在使用Hive CLI或者Beeline CLI的时候指定配置参数。这种方式的配置在整个的会话session中有效,会话结束,失效。
比如在启动hive服务的时候,为了更好的查看启动详情,可以通过hiveconf参数修改日志级别:

$HIVE_HOME/bin/hive --hiveconf hive.root.logger=DEBUG,consol

方式3:set命令

Hive CLI或Beeline中使用set命令为set命令之后的所有SQL语句设置配置参数,这个也是会话级别的。

这种方式也是用户日常开发中使用最多的一种配置参数方式。因为Hive倡导一种:谁需要、谁配置、谁使用的一种思想,避免你的属性修改影响其他用户的修改。

#启用hive动态分区,需要在hive会话中设置两个参数:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;

方式4:服务器特定的配置文件

您可以设置特定metastore的配置值hivemetastore-site.xml中,并在HiveServer2特定的配置值hiveserver2-site.xml中。

Hive Metastore服务器读取$ HIVE_CONF_DIR或类路径中可用的hive-site.xml以及hivemetastore-site.xml配置文件。

HiveServer2读取$ HIVE_CONF_DIR或类路径中可用的hive-site.xml以及hiveserver2-site.xml。

如果HiveServer2以嵌入式模式使用元存储,则还将加载hivemetastore-site.xml。

概况总结

配置文件的优先顺序如下,后面的优先级越高:

hive-site.xml-> hivemetastore-site.xml-> hiveserver2-site.xml->' -hiveconf'命令行参数

从Hive 0.14.0开始,会从HiveConf.java类中直接生成配置模板文件hive-default.xml.template,它是当前版本配置变量及其默认值的可靠来源。

hive-default.xml.template 位于安装根目录下的conf目录中,并且 hive-site.xml 也应在同一目录中创建。

从 Hive 0.14.0开始, 您可以使用SHOW CONF命令显示有关配置变量的信息。

配置方式的优先级顺序,优先级依次递增:

set参数生命>hiveconf命令行参数>hive-site.xml配置文件。

set参数声明覆盖命令行参数hiveconf,命令行参数覆盖配置文件hive-site.xml设定

日常的开发使用中,如果不是核心的需要全局修改的参数属性,建议大家使用set命令进行设置。

另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。

六、Hive初体验

6.1 Hive使用起来和Mysql差不多吗?

背景

对于初次接触Apache Hive的人来说,最大的疑惑就是:Hive从数据模型看起来和关系型数据库mysql等好像。包括Hive SQL也是一种类SQL语言。那么实际使用起来如何?

过程

体验步骤:按照mysql的思维,在hive中创建、切换数据库,创建表并执行插入数据操作,最后查询是否插入成功。

create database itcast;--创建数据库
show databases;--列出所有数据库
use itcast;--切换数据库

img

-建表
create table t_student(id int,name varchar(255));
--插入一条数据
insert into table t_student values(1,"allen");
--查询表数据
select * from t_student;

在执行插入数据的时候,发现插入速度极慢,sql执行时间很长,为什么?
img

最终插入一条数据,历史30秒的时间。
img

查询表数据,显示数据插入成功
img

验证

首先登陆Hadoop YARN上观察是否有MapReduce任务执行痕迹。
YARN Web UI: http://resourcemanager_host:8088/
然后登陆Hadoop HDFS浏览文件系统,根据Hive的数据模型,表的数据最终是存储在HDFS和表对应的文件夹下的。
HDFS Web UI: http://namenode_host:9870/

结论

  • Hive SQL语法和标准SQL很类似,使得学习成本降低不少。
  • Hive底层是通过MapReduce执行的数据插入动作,所以速度慢。
  • 如果大数据集这么一条一条插入的话是非常不现实的,成本极高。
  • Hive应该具有自己特有的数据插入表方式,结构化文件映射成为表。

6.2 体验2:如何才能将结构化数据映射成为表?

背景

在Hive中,使用insert+values语句插入数据,底层是通过MapReduce执行的,效率十分低下。此时回到Hive的本质上:可以将结构化的数据文件映射成为一张表,并提供基于表的SQL查询分析。
假如,现在有一份结构化的数据文件,如何才能映射成功呢?在映射成功的过程中需要注意哪些问题?不妨猜想文件的存储路径?字段类型?字段顺序?字段之间的分隔符问题?

过程

在HDFS根目录下创建一个结构化数据文件user.txt,里面内容如下

1,zhangsan,18,beijing
2,lisi,25,shanghai
3,allen,30,shanghai
4,woon,15,nanjing
5,james,45,hangzhou
6,tony,26,beijing

img

在hive中创建一张表t_user。注意:字段的类型顺序要和文件中字段保持一致。

create table t_user(id int,name varchar(255),age int,city varchar(255));

验证

执行数据查询操作,发现表中并没有数据。
猜想:难道数据文件要放置在表对应的HDFS路径下才可以成功?
img

再次执行查询操作,显示如下,都是null:
img

表感知到结构化文件的存在,但是并没有正确识别文件中的数据。猜想:还需要指定文件中字段之间的分隔符?重建张新表,指定分隔符。

--建表语句 增加分隔符指定语句
create table t_user_1(id int,name varchar(255),age int,city varchar(255))
row format delimited
fields terminated by ',';
--关于分隔符语法 后续学习展开

#把user.txt文件从本地文件系统上传到hdfs
hadoop fs -put user.txt /user/hive/warehouse/itcast.db/t_user_1/

--执行查询操作
select * from t_user_1;

img

此时再创建一张表,保存分隔符语法,但是故意使得字段类型和文件中不一致。

--建表语句 增加分隔符指定语句
create table t_user_2(id int,name int,age varchar(255),city varchar(255))
row format delimited
fields terminated by ',';
#把user.txt文件从本地文件系统上传到hdfs
hadoop fs -put user.txt /user/hive/warehouse/itcast.db/t_user_2/

--执行查询操作
select * from t_user_2;

img

此时发现,有的列显示null,有的列显示正常。

name字段本身是字符串,但是建表的时候指定int,类型转换不成功;age是数值类型,建表指定字符串类型,可以转换成功。说明hive中具有自带的类型转换功能,但是不一定保证转换成功。

结论

  • 要想在hive中创建表跟结构化文件映射成功,需要注意以下几个方面问题:
  • 创建表时,字段顺序、字段类型要和文件中保持一致。
  • 如果类型不一致,hive会尝试转换,但是不保证转换成功。不成功显示null。
  • 文件好像要放置在Hive表对应的HDFS目录下,其他路径可以吗?
  • 建表的时候好像要根据文件内容指定分隔符,不指定可以吗?

6.3 体验3:使用hive进行小数据分析如何?

背景

因为Hive是基于HDFS进行文件的存储,所以理论上能够支持的数据存储规模很大,天生适合大数据分析。假如Hive中的数据是小数据,再使用Hive开展分析效率如何呢?

过程

之前我们创建好了一张表t_user_1,现在通过Hive SQL找出当中年龄大于20岁的有几个。

img

验证

--执行查询操作
select count(*) from t_user_1 where age > 20;

发现又是通过MapReduce程序执行的数据查询功能。

结论

  • Hive底层的确是通过MapReduce执行引擎来处理数据的
  • 执行完一个MapReduce程序需要的时间不短
  • 如果是小数据集,使用hive进行分析将得不偿失,延迟很高
  • 如果是大数据集,使用hive进行分析,底层MapReduce分布式计算,很爽
posted @ 2022-01-09 14:26  王陸  阅读(720)  评论(0编辑  收藏  举报