一、Hive简介
是什么
基于Hadoop的数据仓库工具(管理不存储数据),将hdfs上的结构化数据映射成一张表,提供类sql查询功能
干什么
海量、结构化数据、查询计算
本质
把HQL转换成MapReduce程序
- sql中的查询语句写成MapReduce模板封装在Hive中(数据仓库是通过sql进行统计分析的)
- Hive框架把用户写的sql匹配成相应的MapReduce程序
- MapReduce程序运行并产生分析结果返回给用户
二、Hive特点
注意点
- Hive处理的数据存储在hdfs
- Hive分析数据底层的默认实现是MapReduce
(也可以修改成spark,spark更快) - 执行程序运行在Yarn上
优点
- 容易操作,工作效率高;学习成本低
- 执行延迟高;适用于离线处理大数据(不适用处理小数据)
- 支持自定义函数
缺点
- HQL无法进行迭代式运算(迭代太慢了),不擅长数据挖掘
- Hive自动生成的MapReduce不够快
- Hive调优困难,粒度粗
(MapReduce模板是提前写好的,没有直接写MapReduce灵活)
三、Hive架构
- 元数据:使用外接数据库存储元数据(mysql),文件路径、表结构等信息
- 解析器:解析HQL是否正确
- 编译器:将HQL编译成逻辑任务
- 优化器:优化查询逻辑
- 执行器:把逻辑任务转化为MapReduce执行
Hive与Hadoop之间的工作流程
1、执行的解析和编译
- 客户端将执行命令发送给数据库驱动器
- 驱动器将命令发送给解析器与编译器,进行命令检查与编译
- 编译器将编译好的请求发送给数据库
- 数据库返回元数据给编译器,编译器检查需求
- 优化器优化逻辑后将执行计划发送给驱动器
2、MapReduce作业
- 数据库驱动器将执行计划发送给执行引擎
- 执行引擎将执行计划发送到名称节点中的JobTracker,以分配该作业
- JobTracker将该作业分配给数据节点中的TaskTracker中,查询执行MapReduce作业
- Data节点将作业结果返回到执行引擎
- 执行引擎将结果返回数据库驱动器
- 驱动器将结果返回客户端
四、Hive数据管理与存储
元数据管理
- Metastore:存储仓库中各种表和分区的所有结构信息的组件
- Metastore存储信息:底层数据的位置、文件输入和输出格式以及存储信息。SerDe元数据包括序列化器和解串器的实现类以及实现所需的任何支持信息
- Metastore存储方式 :
默认的Derby数据库
只能由一个Hive服务使用数据库,Derby Metastore只用于单元测试,存储单元测试的数据。
本地模式(常用本地MySQL)
需要配置本地的MySQL服务器,即Hive和MySQL在同一台服务器。
远程模式(常用远程MySQL)
需要配置远程的MySQL服务器,并在Hive客户端期启动meta服务。可以用于任何用途,也是最适合生产的模式,分为服务器和数据存储区,Hive客户端会与Metastore服务器建立连接,经服务器查询数据存储区(如Mysql)获取元数据。
数据存储形式
- 表:在hdfs路径里是一个文件夹
- 分区:每个表可以有一个或者多个用于决定数据如何存储的分区列,但分区列不是数据本身的一部分,而是源于数据加载(如:建表的时候不设置分区的列为字段)
- 桶:每个分区的数据,基于表的一些列的哈希函数值,又被分割成桶
hive文件存储路径
- 表:hive中的表都存储在hdfs上
默认路径是hdfs://机器名:端口/user/hive/warehouse(可以通过${HIVE_HOME}/conf/hive-site.xml配置文件中的hive.metastore.warehouse.dir属性来配置其他路径) - 分区:分区存储在hdfs上对应表的路径底下,是文件夹
- 桶:存储在分区所在路径,将一个分区表区分为很多文件
根据指定列的hash值切分分区表数据,目的是为了并行,每一个桶对应一个文件(如:/user/hive/warehouse/table)name/part-00000,/user/hive/warehouse/table_name/part-00002)
五、Hive与数据库比较
不同项 | Hive | 数据库 |
---|---|---|
数据量 | 大数据 | 小数据 |
数据存储 | hdfs | 地文件系统或块设备 |
查询速度 | 慢 (Hive与MapReduce都延迟高) | 快(仅限于小数据) |
扩展性 | 高,与hadoop一致,4000台所有 | 低,差不多200台封顶 |
索引 | 不能建索引,遍历查询所有满足条件的数据 | 可建索引,使查询更快 |
数据改动 | 改动频率小,数据基于hdfs,稳定性高 | 随时改动 |
计算 | 类sql(本质是MapReduce任务) | sql |
六、数据类型
基本数据类型
标识 | 数据类型 |
---|---|
INT | 4byte整数 |
BIGINT | 8byte整数 |
STRING | 字符 |
DOUBLE | 双精度 |
TIMESTAMP | 双时类型 |
TINYINT | 1byte整数 |
SMALINT | 2byte整数 |
FLOAT | 单精度 |
BOOLEAN | 单布尔型 |
BINARY | 字节数组 |
集合类型
了解就行,生产环境中,会用自定义函数对集合类型进行处理,处理成扁平化数据
- STRUCT{} 结构,用点符号访问元素
(struct.元素标识名) - MAP{} 键值对,用key访问value
(map[“key”]) - ARRAY{} 数组,用角标访问元素
(array[0])
示例:基于json文件确定表结构,并建表,load测试数据
json文件
{
“name”:“song”,
“friends”:{“bing”,“li”},
“children”:{“xiao song”:18,“xiaoxiao song”:19},
“address”:{“street”:“zhuque”,“city”:“xian”}
}
Hive上创建测试表test
一张表中三种集合类型用的元素分隔符要一致
hive> 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 '_' #集合分隔符,包含array、map、struct三种集合的元素分隔符
map keys terminated by ':' #键值对分隔符
lines terminated by '\n'; #行分隔符
新建本地测试文件test.txt(json文件的结构不能直接作为数据)
[root@Hadoop01 /]# cd /srv/
[root@Hadoop01 srv]# mkdir -p ./data/byy
[root@Hadoop01 srv]# cd data/byy
[root@Hadoop01 byy]# vim test.txt
song,bing_li,xiao song:18_xiaoxiao song:19,zhuque_xian
xue,zhang_bai,xiao xue:12,xiaoxiao xue:19,jinye_xian
#保存退出
把test.txt文件load进表test
hive> load data local inpath '/srv/data/byy/test.txt' into table test;
#查询表数据
hive> select * from test;
OK
song ["bing","li"] {"xiao song":18,"xiaoxiao song":19} {"street":"zhuque","city":"xian"}
xue ["zhang","bai"] {"xiao xue":12} {"street":"xiaoxiao xue:19","city":null}
Time taken: 0.132 seconds, Fetched: 2 row(s)
hive> select friends[1] from test;
OK
li
bai
Time taken: 0.175 seconds, Fetched: 2 row(s)
hive> select children["xiao song"] from test;
OK
18
NULL
Time taken: 0.102 seconds, Fetched: 2 row(s)
hive> select address.street from test;
OK
zhuque
xiaoxiao xue:19
Time taken: 0.081 seconds, Fetched: 2 row(s)
类型转化
隐式转化(自动转化)规则
- 整型,可以转化为范围更广的整型
(INT可以转化为BIGINT,但BIGINT不能转化为INT) - 所有整型、FLOAT、数值的STRING可以转化为DOUBLE
- 整型中除了BIGINT都可以转化为FLOAT
- BOOLEAN不可以转化为任何类型
强制转化
- cast(对象 as 数据类型)
eg:cast(‘1’ as INT) - 当转化失败时,返回空值null