大数据之——Hive


学习: 尚硅谷-Hive

1. Hive 基本概念

1.1 什么是 Hive

1) hive 简介

Hive:由 Facebook 开源用于解决海量结构化日志的数据统计工具。

Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并 提供类 SQL 查询功能。

2) Hive 本质:将 HQL 转化成 MapReduce 程序

1.2 Hive 的优缺点

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 架构原理

在这里插入图片描述

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。

在这里插入图片描述

Hive 通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的 Driver, 结合元数据(MetaStore),将这些指令翻译成 MapReduce,提交到 Hadoop 中执行,最后,将 执行返回的结果输出到用户交互接口

2. Hive 安装

2.1 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

2.2Hive 安装部署

2.2.1 安装 Hive

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

2)解压 apache-hive-3.1.2-bin.tar.gz 到/opt/module/目录下面

[tao@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

[tao@hadoop102 module]$ mv apache-hive-3.1.2-bin/ hive

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

[tao@hadoop102 module]$ sudo vim /etc/profile.d/my_env.sh
#HIVE_HOME
export HIVE_HOME=/opt/module/hive
export PATH=$PATH:$HIVE_HOME/bin

[tao@hadoop102 hive]$ source /etc/profile

6)解决日志 Jar 包冲突(可选择)

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

7)初始化元数据库

[tao@hadoop102 hive]$  bin/schematool -dbType derby -initSchema

2.2.2 启动并使用 Hive

1)启动 Hive

## Hadoop 中的脚本  启动Hadoop
[tao@hadoop102 hive]$ myhadoop.sh start

[tao@hadoop102 hive]$   bin/hive

2)使用 Hive

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

默认存储路径

/user/hive/warehouse/test

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

监控日志

[tao@hadoop102 tao]$ cd /tmp/tao
[tao@hadoop102 tao]$ ll
总用量 148
-rw-rw-r--. 1 tao tao 147606 1118 20:49 hive.log
[tao@hadoop102 tao]$ tail -f hive.log 

2.3MySQL 安装

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

[tao@hadoop102 ~]$ rpm -qa|grep mariadb

# 出现 mariadb-libs-5.5.56-2.el7.x86_64 
# 删除
[tao@hadoop102 ~]$ sudo rpm -e --nodeps mariadb-libs
## 再次检查就没有

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

3)解压 MySQL 安装包

[tao@hadoop102 software]$ tar -xf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar 

4)在安装目录下执行 rpm 安装

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

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

查看 datadir 的值:

cat /etc/my.cnf 

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

[tao@hadoop102 mysql]$ sudo rm -rf ./*

6)初始化数据库

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

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-01dY8HFV-1668853155970)(pics/image-20221118170223229.png)]

8)启动 MySQL 服务

[tao@hadoop102 opt]$ sudo systemctl start mysqld

9)登录 MySQL 数据库

临时密码:w7pjoO3NjH=d

 [tao@hadoop102 opt]$ mysql -uroot -p

10)必须先修改 root 用户的密码,否则执行其他的操作会报错

mysql> set password = password("新密码"); #123456

11)修改 mysql 库下的 user 表中的 root 用户允许任意 ip 连接

mysql> update mysql.user set host='%' where user='root';
mysql> flush privileges;
## 系统表
mysql> show databases;
mysql> use mysql

2.4 Hive 元数据配置到 MySQL

2.4.1 拷贝驱动

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

[tao@hadoop102 software]$ cp /opt/software/mysql-connector-java-5.1.27-bin.jar $HIVE_HOME/lib

2.4.2 配置 Metastore 到 MySQL

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

vim $HIVE_HOME/conf/hive-site.xml
<?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://hadoop102:3306/metastore?useSSL=false</value>
    </property>

    <!-- jdbc 连接的 Driver-->
    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.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>000000</value>
    </property>

    <!-- Hive 元数据存储版本的验证 -->
    <property>
        <name>hive.metastore.schema.verification</name>
        <value>false</value>
    </property>

    <!--元数据存储授权-->
    <property>
        <name>hive.metastore.event.db.notification.api.auth</name>
        <value>false</value>
    </property>

    <!-- Hive 默认在 HDFS 的工作目录 -->
    <property>
        <name>hive.metastore.warehouse.dir</name>
        <value>/user/hive/warehouse</value>
    </property>
</configuration>

2)登陆 MySQL

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

3)新建 Hive 元数据库

mysql> create database metastore;
mysql> quit;

4) 初始化 Hive 元数据库

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

2.4.3 再次启动 Hive

1)启动 Hive

[tao@hadoop102 hive]$ bin/hive

2)使用 Hive

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

这样就支持多用户操作 从derby 迁移-> mysql

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

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

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

只要配置这个 就必须通过 启动元数据服务去连

2)启动 metastore

[tao@hadoop102 hive]$ hive --service metastore
2022-11-18 20:34:08: Starting Hive Metastore Server

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

3)启动 hive

[tao@hadoop102 hive]$ bin/hive

2.6 使用 JDBC 方式访问 Hive

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

<!-- 指定 hiveserver2 连接的 host -->
<property>
    <name>hive.server2.thrift.bind.host</name>
    <value>hadoop102</value>
</property>
<!-- 指定 hiveserver2 连接的端口号 -->
<property>
    <name>hive.server2.thrift.port</name>
    <value>10000</value>
</property>

这种方式其实就是通过

hiveserver2连接 元数据服务实现的 再通过JDBC(mysql驱动)连接Mysql 所以元数据服务也要开启

客户端 通过JDBC(Hive驱动) 连接 hiveserver2

2)启动 hiveserver2

先开启元数据服务

 [tao@hadoop102 hive]$ bin/hive --service metastore
 [tao@hadoop102 hive]$ bin/hive --service hiveserver2

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

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

这就是没连上

解决办法:

步骤:

1. 在hadoop中/etc/hadoop/core-site.xml(这是我的路径:/opt/module/hadoop-3.1.3/etc/hadoop/core-site.xml)增加如下配置

2. 用xsync命令分发core-site.xml

3.把metastore和hiveserver2停了(kill -9 run进程号),然后关闭再开启hadoop集群

4.开启metastore和hiveserver2,继续报错前的操作
<property>
    <name>hadoop.proxyuser.xxx.hosts</name>
    <value>*</value>
</property>
<property>
    <name>hadoop.proxyuser.xxx.groups</name>
    <value>*</value>
</property>

这样就连接上了

4)看到如上界面

5)编写 hive 服务启动脚本(了解)

#!/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
&"
 [ -z "$metapid" ] && eval $cmd || echo "Metastroe 服务已启动"
 server2pid=$(check_process HiveServer2 10000)
 cmd="nohup 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

这边直接省略。。。。。。。。

注释文件 直接直连

<?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://hadoop102:3306/metastore?useSSL=false</value>
    </property>

    <!-- jdbc 连接的 Driver-->
    <property>
        <name>javax.jdo.option.ConnectionDriverName</name>
        <value>com.mysql.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>123456</value>
    </property>

    <!-- Hive 元数据存储版本的验证 -->
    <property>
        <name>hive.metastore.schema.verification</name>
        <value>false</value>
    </property>

    <!--元数据存储授权-->
    <property>
        <name>hive.metastore.event.db.notification.api.auth</name>
        <value>false</value>
    </property>

    <!-- Hive 默认在 HDFS 的工作目录 -->
    <property>
        <name>hive.metastore.warehouse.dir</name>
        <value>/user/hive/warehouse</value>
    </property>


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


    <!-- 指定 hiveserver2 连接的 host -->
<!--    <property>
        <name>hive.server2.thrift.bind.host</name>
        <value>hadoop102</value>
    </property> -->

    <!-- 指定 hiveserver2 连接的端口号 -->
<!--    <property>
        <name>hive.server2.thrift.port</name>
        <value>10000</value>
    </property> -->


</configuration>

此时就是恢复直连接方式

启动Hive 和当初一样

## 启动hadoop
[tao@hadoop102 hive]$ myhadoop.sh start
## 启动Hive
[tao@hadoop102 hive]$  bin/hive

2.7 Hive 常用交互命令

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

bin/hive -e "select id from student;"

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

2.8 Hive 其他命令操作

1)退出 hive 窗口:

hive(default)>exit;
hive(default)>quit;

2)在 hive cli 命令窗口中如何查看 hdfs 文件系统

hive(default)>dfs -ls /;

3)查看在 hive 中输入的所有历史命令

u@hadoop102 ~]$ cat .hivehistory

2.9 Hive 常见属性配置

2.9.1 Hive 运行日志信息配置

1)Hive 的 log 默认存放在/tmp/tao/hive.log 目录下(当前用户名下)

2)修改 hive 的 log 存放日志到/opt/module/hive/logs

(1)修改/opt/module/hive/conf/hive-log4j2.properties.template 文件名称为

hive-log4j2.properties

[tao@hadoop102 conf]$ mv hive-log4j2.properties.template hive-log4j2.properties

(2) 在 hive-log4j2.properties 文件中修改 log 存放位置

hive.log.dir=/opt/module/hive/logs

2.9.2 打印 当前库 和 表头

在 hive-site.xml 中加入如下两个配置:

<property>
    <name>hive.cli.print.header</name>
    <value>true</value>
</property>
<property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
</property>

2.9.3 参数配置方式

1)查看当前所有的配置信息

hive>set;

2)参数的配置三种方式

(1)配置文件方式 默认配置文件:hive-default.xml

用户自定义配置文件:hive-site.xml

注意:用户自定义配置会覆盖默认配置。另外,Hive 也会读入 Hadoop 的配置,因为 Hive 是作为 Hadoop 的客户端启动的,Hive 的配置会覆盖 Hadoop 的配置。配置文件的设定对本 机启动的所有 Hive 进程都有效。

(2)命令行参数方式

启动 Hive 时,可以在命令行添加-hiveconf param=value 来设定参数

例如:

 bin/hive -hiveconf mapred.reduce.tasks=10;

注意:仅对本次 hive 启动有效

查看参数设置:

hive (default)> set mapred.reduce.tasks;

(3)参数声明方式

可以在 HQL 中使用 SET 关键字设定参数

例如:

hive (default)> set mapred.reduce.tasks=100;

注意:仅对本次 hive 启动有效。

上述三种设定方式的优先级依次递增。即配置文件<命令行参数<参数声明。注意某些系 统级的参数,例如 log4j 相关的设定,必须用前两种方式设定,因为那些参数的读取在会话 建立以前已经完成了

3 .Hive 数据类型

3.1 基本数据类型

在这里插入图片描述

对于 Hive 的 String 类型相当于数据库的 varchar 类型,该类型是一个可变的字符串,不 过它不能声明其中最多能存储多少个字符,理论上它可以存储 2GB 的字符数

3.2 集合数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KITxOJNk-1668853155974)(pics/image-20221119155747230.png)]

Hive 有三种复杂数据类型 ARRAY、MAP 和 STRUCT。ARRAY 和 MAP 与 Java 中的 Array 和 Map 类似,而 STRUCT 与 C 语言中的 Struct 类似,它封装了一个命名字段集合,复杂数据 类型允许任意层次的嵌套

1)案例实操

(1)假设某表有如下一行,我们用 JSON 格式来表示其数据结构。在 Hive 下访问的格 式为

{
 "name": "songsong",
 "friends": ["bingbing" , "lili"] , //列表 Array,
 "children": { //键值 Map,
 "xiao song": 18 ,
 "xiaoxiao song": 19
 }
 "address": { //结构 Struct,
 "street": "hui long guan",
 "city": "beijing"
 }
}

(2)基于上述数据结构,我们在 Hive 里创建对应的表,并导入数据。 创建本地测试文件 test.txt

songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing

注意:MAP,STRUCT 和 ARRAY 里的元素间关系都可以用同一个字符表示,这里用“_”

(3)Hive 上创建测试表 test

create table test(
name string,
friends array<string>,
children map<string, int>,
address struct<street:string, city:string>
)
row format delimited fields terminated by ','
collection items terminated by '_'
map keys terminated by ':'
lines terminated by '\n';

(4)导入文本数据到测试表

[tao@hadoop102 hive]$ hadoop fs -put test.txt /user/hive/warehouse/test

(5)访问三种集合列里的数据,以下分别是 ARRAY,MAP,STRUCT 的访问方式

hive (default)> select * from test;

hive (default)> select friends[1],children['xiao song'],address.city from test;

类似SQL 后面再补充

4. Hive-DDL

5. Hive -DML

6. Hive查询

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值