1) hive 简介
Hive:由 Facebook 开源用于解决海量结构化日志的数据统计工具。
Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并 提供类 SQL 查询功能。
2) Hive 本质:将 HQL 转化成 MapReduce 程序
(1)操作接口采用类 SQL 语法,提供快速开发的能力(简单、容易上手)
(2)避免了去写 MapReduce,减少开发人员的学习成本。
(3)Hive 的执行延迟比较高,因此 Hive 常用于数据分析,对实时性要求不高的场合。
(4)Hive 优势在于处理大数据,对于处理小数据没有优势,因为 Hive 的执行延迟比较 高。
(5)Hive 支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
1)Hive 的 HQL 表达能力有限
(1)迭代式算法无法表达
(2)数据挖掘方面不擅长,由于 MapReduce 数据处理流程的限制,效率更高的算法却 无法实现。
2)Hive 的效率比较低
(1)Hive 自动生成的 MapReduce 作业,通常情况下不够智能化
(2)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 中执行,最后,将 执行返回的结果输出到用户交互接口
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.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 11月 18 20:49 hive.log
[tao@hadoop102 tao]$ tail -f hive.log
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
将 MySQL 的 JDBC 驱动拷贝到 Hive 的 lib 目录下
[tao@hadoop102 software]$ cp /opt/software/mysql-connector-java-5.1.27-bin.jar $HIVE_HOME/lib
1)在$HIVE_HOME/conf 目录下新建 hive-site.xml 文件
vim $HIVE_HOME/conf/hive-site.xml
<configuration>
<property>
<name>javax.jdo.option.ConnectionURLname>
<value>jdbc:mysql://hadoop102:3306/metastore?useSSL=falsevalue>
property>
<property>
<name>javax.jdo.option.ConnectionDriverNamename>
<value>com.mysql.jdbc.Drivervalue>
property>
<property>
<name>javax.jdo.option.ConnectionUserNamename>
<value>rootvalue>
property>
<property>
<name>javax.jdo.option.ConnectionPasswordname>
<value>000000value>
property>
<property>
<name>hive.metastore.schema.verificationname>
<value>falsevalue>
property>
<property>
<name>hive.metastore.event.db.notification.api.authname>
<value>falsevalue>
property>
<property>
<name>hive.metastore.warehouse.dirname>
<value>/user/hive/warehousevalue>
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
1)启动 Hive
[tao@hadoop102 hive]$ bin/hive
2)使用 Hive
3)在 CRT 窗口中开启另一个窗口开启 Hive
这样就支持多用户操作 从derby 迁移-> mysql
1)在 hive-site.xml 文件中添加如下配置信息
<property>
<name>hive.metastore.urisname>
<value>thrift://hadoop102:9083value>
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
1)在 hive-site.xml 文件中添加如下配置信息
<property>
<name>hive.server2.thrift.bind.hostname>
<value>hadoop102value>
property>
<property>
<name>hive.server2.thrift.portname>
<value>10000value>
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.hostsname>
<value>*value>
property>
<property>
<name>hadoop.proxyuser.xxx.groupsname>
<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
1)“-e” 不进入 hive 的交互窗口执行 sql 语句
bin/hive -e "select id from student;"
2)“-f” 执行脚本中 sql 语句
1)退出 hive 窗口:
hive(default)>exit;
hive(default)>quit;
2)在 hive cli 命令窗口中如何查看 hdfs 文件系统
hive(default)>dfs -ls /;
3)查看在 hive 中输入的所有历史命令
u@hadoop102 ~]$ cat .hivehistory
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
在 hive-site.xml 中加入如下两个配置:
<property>
<name>hive.cli.print.headername>
<value>truevalue>
property>
<property>
<name>hive.cli.print.current.dbname>
<value>truevalue>
property>
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 相关的设定,必须用前两种方式设定,因为那些参数的读取在会话 建立以前已经完成了
对于 Hive 的 String 类型相当于数据库的 varchar 类型,该类型是一个可变的字符串,不 过它不能声明其中最多能存储多少个字符,理论上它可以存储 2GB 的字符数
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,
children map,
address struct
)
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 后面再补充