目录
6.2.3.Built-in Aggregate Functions (UDAF)实例
6.2.4.Built-in Table-Generating Functions (UDTF) 表生成函数实例
7.6.2 设置map输出和reduce输出进行合并的相关参数:
一、Hive 概述
1.1 Hive 是什么
- 由Facebook开源用于解决海量结构化日志的数据统计
- 基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射成一张表,并且提供类SQL的查询功能
- Hive仅仅是一个工具,本身不存储数据只提供一种管理方式,同时也不涉及分布式概念,就是个软件而已
- Hive本质就是MapReduce,将类SQL(HQL)转换成MapReduce程序
1.1.1 HQL转换MR流程
解释:
- Hive处理的数据存储在HDFS
- Hive分析数据底层默认实现是MapReduce[可以修改为tez或spark]
Hive-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.
- 执行的程序运行在yarn上
- Hive相当于Hadoop的一个客户端
- Hive不是分布式
1.2 Hive 优缺点
1.2.1 优点
- 操作接口采用类SQL语法,提供快速开发的能力(简单、易上手)
- 避免去写MR,减少开发人员学习成本
- Hive的延迟比较高(因为MR延迟高),因此Hive常用于数据分析
- Hive优势在于处理大数据(数据量少真不如MySQL等)
- Hive支持用户自定义函数,可以根据自己的需求实现自己的函数
1.2.2 缺点
Hive的HQL表达能力有限(MR决定的):
- 迭代算法无法表达
- 不适用于数据挖掘
Hive的效率比较低:
- Hive自动生成的MR作业,通常情况不够智能
- Hive调优难(只能对资源,SQL层面调优,无法深入作业底层逻辑
1.3 Hive 架构原理
- 用户接口:Client
CLI(hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive)
- 元数据:Metastore
包括表名、表所属的数据库、表的拥有者、列/分区字段、表的类型、表数据所在的目录等(自带个derby数据库,推荐配置到MySQL)
- 底层存储:HDFS
使用HDFS进行存储,使用MapReduce计算
- 驱动器:Driver
解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,并对语法树进行语法分析,如:SQL语法、表/字符是否存在 编译期(Physical Plan):将AST编译生成逻辑执行计划 优化器(Query Optimizer):对逻辑执行计划进行优化 执行器(Execution):把逻辑执行计算转换成运行的物理计划,即MR/Spark
Hive通过给用户提供的一系列交互接口,接受到用户编写的SQL,使用自己的Driver结合MetaStore,将SQL指令翻译成MapReduce提交到Hadoop中执行,将执行结果输出到用户交互接口。
1.4 Hive 和传统数据库比较
Hive除了提供类似SQL语法外和传统数据库没有任何相似之处,Hive是站在数据仓库出发点而设计的。
1.4.1 数据存储位置
Hive是建立在Hadoop之上,所有的Hive数据都是存储在HDFS上;传统数据库将数据保存在本地文件系统中;因此Hive能够处理更大更多的数据
1.4.2 数据更新
Hive是针对数据仓库应用设计,因此数据一次写入多次读出,即Hive中不建议对数据进行改写操作,所有数据都是在加载的时候确定好;对于数据库通常需要进行频繁的增删查改
1.4.3 索引
Hive在加载数据过程不会对数据进行任何处理,因为数据量庞大建立索引并不划算,因此Hive访问数据中满足特定值需要暴力扫描真个数据,因此访问延迟高。由于MapReduce的引入,Hive可以并行访问数据,即便没有索引也可用于大数据量的访问;传统数据库通常针对一个或多个列建立索引,因此在访问数据是延迟低效率高,即Hive不适合实时数据分析
1.4.4 执行
Hive 的执行引擎为MR/Spark,传统数据库都有自己的执行引擎
1.4.5 可拓展性
由于Hadoop的高拓展性,因此Hive也具备很强的拓展性;传统数据库的拓展会受到一定的限制
1.4.6 数据规模
Hive可以利用MapReduce进行大规模数据的并行计算;传统数据库支持的数据规模较小
二、Hive 基础
2.1 Hive 版本的选择
建议使用 1.x 版本 hive-3.1.2
只需要在一个节点上安装(Master节点)
2.2. 步骤
-
下载
hive.apache.org -
拷贝到linux
winscp
设置共享文件夹 -
解压
tar -zxvf apache-hive-1.2.1-bin.tar.gz -C /opt/programfile/ -
配置环境变量(/etc/profile)
export HIVE_HOME=/opt/programfile/hive export PATH= $PATH:$HIVE_HOME/bin
使新的配置生效:source /etc/profile
-
Hive的基本配置
改名
cp hive-env.sh.template hive-env.sh修改配置(指定hadoop的路径,因为hive基于Hadoop运行的)
HADOOP_HOME=/opt/programfile/hadoop
export HIVE_CONF_DIR=/opt/programfile/hive/conf开启集群
start-dfs.sh
start-yarn.sh配置数据仓库的存储路径(数据最终存储在HDFS上)(在HDFS上配置的路径)
注意:此路径需要具有写权限创建数据存储目录:
hdfs dfs -mkdir /tmp
hdfs dfs -mkdir -p /user/hive/warehouse修改权限:
hdfs dfs -chmod 777 /tmp
hdfs dfs -chmod 777 /user/hive/warehouse配置日志的存储位置:
日志文件默认存储位置:/tmp/zhangsan/hive.log 设置用户自定义的存储位置: 1. 创建 hive-log4j.properties cp hive-log4j.properties.template hive-log4j.properties 2. 修改参数 hive.log.dir=/opt/programfile/hive/logs 3. 重新进入hive,当前日志文件所在的路径发生的变更
hive-site.xml中进行配置
配置数据仓库的位置: <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive/warehouse</value> </property> 配置当前数据库提示信息: <property> <name>hive.cli.print.current.db</name> <value>false</value> </property> 配置查询结果的字段提示信息: <property> <name>hive.cli.print.header</name> <value>true</value> </property>
-
将元数据配置到MySQL中需要初始化,初始化命令(其余步骤可自行百度):
schematool -dbType mysql -initSchema
MySQL管理:
(1)查看mysql服务是否启动
ps -ef|grep mysqld(2)启动、关闭mysql服务
service mysqld restart 重启
service mysqld start 启动
service mysqld stop 停止(3)配置文件
/etc/my.cnf(4)常见管理命令
USE 数据库名 使用数据库
SHOW DATABASES 列出 MySQL 数据库管理系统的数据库列表
SHOW TABLES 显示指定数据库的所有表
SHOW COLUMNS FROM 数据表 显示数据表的属性
SHOW INDEX FROM 数据表 显示数据表的详细索引信息
SHOW TABLE STATUS LIKE [FROM db_name] [LIKE 'pattern'] \G: 该命令将输出Mysql数据库管理系统的性能及统计信息。 -
Hive元数据存到到MySQL的参数配置
目的:hive如何能连接上mysql
步骤:
1. 驱动
mv /opt/software/mysql-connection-java-xxx.jar /opt/programfile/hive/lib/
2. 连接mysql参数配置:user password driver url
hive-default.xml.template , hive的配置文件模板
3. 创建一个配置文件:hive-site.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://192.168.175.200:3306/metastore?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
</configuration>
2.3 Hive 基本操作
- 启动hive
[root@master hive-3.2.1]# hive
- 查看数据库
hive (hive)> show databases; OK database_name default hive Time taken: 0.02 seconds, Fetched: 2 row(s)
hive自带一个default数据库,默认也是进这个数据库
-
切换数据库
hive (hive)> use hive; OK Time taken: 0.031 seconds
-
创建表
hive (hive)> create table if not exists tbl_1(id int,name string); OK Time taken: 0.628 seconds
和MySQL语法基本一致,只是Hive的数据类型和Java类似
-
查看表结构
hive (hive)> desc tbl_1; OK col_name data_type comment id int name string Time taken: 0.084 seconds, Fetched: 2 row(s) -------------------- 分隔符 ------------------- # 查看表的详细信息 hive (hive)> desc formatted tbl_1; OK col_name data_type comment # col_name data_type comment id int name string # Detailed Table Information Database: hive OwnerType: USER Owner: root CreateTime: Wed Aug 26 19:55:58 CST 2020 LastAccessTime: UNKNOWN Retention: 0 Location: hdfs://master:9000/user/hive/warehouse/hive.db/tbl_1 Table Type: MANAGED_TABLE Table Parameters: COLUMN_STATS_ACCURATE {\"BASIC_STATS\":\"true\",\"COLUMN_STATS\":{\"id\":\"true\",\"name\":\"true\"}} bucketing_version 2 numFiles 0 numRows 0 rawDataSize 0 totalSize 0 transient_lastDdlTime 1598442958 # Storage Information SerDe Library: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe InputFormat: org.apache.hadoop.mapred.TextInputFormat OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat Compressed: No Num Buckets: -1 Bucket Columns: [] Sort Columns: [] Storage Desc Params: serialization.format 1 Time taken: 0.154 seconds, Fetched: 32 row(s)
-
插入数据(不要用,不要用,不要用)
hive (hive)> insert into tbl_1 values(1,'zhangsan'); ... ... ... Time taken: 84.754 seconds
-
查询数据
hive (hive)> select * from tbl_1; OK tbl_1.id tbl_1.name 1 zhangsan Time taken: 0.214 seconds, Fetched: 1 row(s)
-
退出hive
hive (hive)> quit;
-
执行hdfs shell
hive (hive)> dfs -ls /; Found 3 items drwxr-xr-x - root supergroup 0 2020-07-21 15:57 /HBase drwx-wx-wx - root supergroup 0 2020-07-21 18:27 /tmp drwxrwxrwx - root supergroup 0 2020-07-21 18:00 /user hive (default)> dfs ls /user/hive/;
-
执行linux shell
hive (hive)> !pwd; /usr/local/soft/hive-3.2.1 hive (default)> ! ls /home/zhangsan; //查看本地的文件系统
-
查看hive操作的历史记录
[hadoop@master /home/hadoop]$ cat .hivehistory
2.4 Hive 常规操作
问题:插入一条数据84秒,比较耗时。显然不现实…
hive (hive)> insert into tbl_1 values(1,'zhangsan');
...
...
...
Time taken: 84.754 seconds
为此Hive插入数据将采用最暴力最直接的方式,只需要将数据文件放到hdfs制定的路径即可。但也不是什么数据都可以,需要在创建表时指定分隔符
hive (hive)> create table if not exists tbl_2(id int,name string)
> row format delimited fields terminated by '\t';
OK
Time taken: 0.118 seconds
准备数据:
[root@master data]# cat student.txt
1 zhangsan
2 lisi
3 wangwu
4 zhaoliu
5 tianqi
[root@master data]# pwd
/usr/local/soft/hive-3.2.1/data
2.4.1 hive 插入数据方式一
加载本地数据到hive
hive (hive)> load data local inpath '/usr/local/soft/hive-3.2.1/data/student.txt' into table tbl_2;
Loading data to table hive.tbl_2
OK
Time taken: 0.311 seconds
hive (hive)> select * from tbl_2;
OK
tbl_2.id tbl_2.name
1 zhangsan
2 lisi
3 wangwu
4 zhaoliu
5 tianqi
Time taken: 0.192 seconds, Fetched: 5 row(s)
评价:方便、推荐使用
2.4.2 hive 插入数据方式二
hive管理的数据是放在hdfs,可以再配置文件指定存储路径,可以进入指定路径查看,也可以通过desc formatted 表名
看到该表的存储路径
- hive在hdfs存储的根路径是在/…/warehouse/下
- 一个数据库对应一个文件夹,命名方式为数据库名.db(默认数据库除外)
- 每张表也对应一个文件夹,命名方式为表名
- 数据文件直接放在表对应的文件夹下,因此通过load方式其实底层调用的是hadoop fs -put
- 默认数据库下的表直接放在warehouse下命名方式不变
基于上述规律可以有第二种插入方式,直接通过hadoop的shell将文件put到指定的hdfs路径下即可
[root@master data]# hadoop fs -put student.txt /user/hive/warehouse/hive.db/tbl_2/student_1.txt
hive (hive)> select * from tbl_2;
OK
tbl_2.id tbl_2.name
1 zhangsan
2 lisi
3 wangwu
4 zhaoliu
5 tianqi
1 zhangsan
2 lisi
3 wangwu
4 zhaoliu
5 tianqi
Time taken: 0.396 seconds, Fetched: 10 row(s)
总结:也可以用,但是必须知道表在hdfs上的路径,所以这种方式较为受限!
看过hive数据库、表、数据在hdfs上的存储结构后,尝试再次加载一次数据,这次通过load加载hdfs上的数据
hive (hive)> load data inpath '/student.txt' into table tbl_2;
Loading data to table hive.tbl_2
OK
Time taken: 0.683 seconds
load方式加载hdfs文件不需要加local(很显然),这时候再次查看hdfs信息,此时原数据将会被删除(其实就是hadoop fs -mv)
对于多次加载相同数据文件情况,hive会将数据文件重命名后上传到hdfs指定路径,重命名格式:原文件名_copy_n.txt;和windows下同名文件处理类似。
2.5 Hive 数据类型
2.5.1 基本数据类型
Hive数据类型 | Java数据类型 | 长度 |
---|---|---|
tinyint | byte | 1byte |
smalint | short | 2byte |
int | int | 4byte |
bigint | long | 8byte |
boolean | boolean | true/false |
float | float | 单精度 |
double | double | 双精度 |
string | String | 字符串 |
timestamp | ||
bigary |
常用的基本数据类型有int、bigint、double、string且不区分大小写;boolean一般使用0/1代替以减少存储量;string使用最多,一般都是处理日志,理论上可以存储2G数据(一行)。
2.5.2 集合数据类型
数据类型 | 描述 | 语法实例 |
struct | 结构体,复杂无关系数据 | struct |
map | 字典,键值对元组集合 | map |
array | 数组,同一类型集合 | array |
struct和map区别在于map只能存储一组一组的k-v对,且一个map中的k不能相同,struct可以存储很对组相同key不同value的数据结构,即map中每组数据的key都不相同,struct中每组数据对应位置的key都是一样的;集合数据类型允许任意层次的嵌套。
复杂数据类型:array、map、struct
Array:
create table arr_tb(name string,score Array<double>)
row format delimited fields terminated by '\t' # 设置每行中