Hive
1、概念
基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL的查询功能。
2、优缺点
优点
接口采用类SQL语法,提供快速开发的能力
避免了去写MR程序,
Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合
Hive的优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高
Hive支持自定义函数,用户可以根据自己的需求来实现自己的函数
缺点
Hive的HSQL表达能力有限
迭代算法无法表达
数据挖掘方面不擅长,由于MR数据处理流程的限制,效率更高的算法却无法实现
Hive的效率 比较低
Hive自动生成的MR作业,通常情况下不够智能化
Hive调优比较困难,粒度较粗
3、架构
3-1、Hive的核心
Hive的核心是驱动引擎,驱动引擎由四部分组成:
- 解释器:解释器的作用是将HiveSQL语句转换为语法树(AST)。
- 编译器:编译器是将语法树编译为逻辑执行计划。
- 优化器:优化器是对逻辑执行计划进行优化。
- 执行器:执行器是调用底层的运行框架执行逻辑执行计划。
3-2、Hive的底层存储
Hive的数据是存储在HDFS上的。Hive中的库和表可以看作是对HDFS上数据做的一个映射。所以Hive必须是运行在一个Hadoop集群上的。(他是要依赖hdfs的,因为他的数据全以文件的形式存在这的(hdfs://cdh02:8020/user/hive/warehouse/XXX.db/XXX),每个hive表的LOCATION都对应一个hdfs的路)
3-3、Hive语句的执行过程
Hive中的执行器,是将最终要执行的MapReduce程序放到YARN上以一系列Job的方式去执行。
创建表
-- EXTERNAL表示创建的是一张外部表
CREATE [EXTERNAL] TABLE `你的表名`(
`carOwner` string COMMENT '车主',
`type` int COMMENT '类型'
)
COMMENT '设备文件表'
-- 创建分区dt(分区名不能和上面的字段名相同)
PARTITIONED BY (
`dt` string)
row format delimited fields terminated by '\t'
-- 规定存储文件格式,默认为textfile(可读性比较好,不过比较占空间),推荐:orc(读取速度快)
STORED AS textfile[orc|sequencefile|Parquet]
4、分区
1、创建分区
## 创建一级分区
create table partition_table(
col1 int,
col2 string
)
-- ## 创建的分区字段不能与上面的字段名字相同
partitioned by (part_col string)
-- 设置\t为分隔符
row format delimited fields terminated by '\t';
## 创建二级分区
create table partition_table(
col1 int,
col2 string
)
-- ## 二级分区相当于在一级分区对应的目录上新增一个目录,一般用于单个分区数据量很大,需要做拆解的情况。
partitioned by (part_col1 string, part_col2 string)
row format delimited fields terminated by '\t';
2、导入数据
# 目的就是将文件放在对应的hdfs文件的路径下
load data [local(存在服务器上)] inpath '/data_dir/data_file' into table partition_table partition(part_col='20220331');
3、查看分区
show partitions partition_table;
4、添加【删除】分区
alter table partition_table add【drop】 partition(part_col='20220331');
5、动态分区
# 开启动态分区功能(默认 true,开启)
hive.exec.dynamic.partition=true
# 设置为非严格模式
# 默认 strict,表示至少指定一个分区为静态分区,nonstrict 表示允许所有的分区字段都能使用动态分区
hive.exec.dynamic.partition.mode=nonstrict
# 在所有执行 MR 的节点上,最大一共可以创建多少个动态分区。默认 1000
hive.exec.max.dynamic.partitions=1000
5、分桶
1、创建分桶
-- 分 6 个桶的分桶表
create table bucket_table(
col1 int,
col2 string
)
clustered by(col1) into 6 buckets
row format delimited fields terminated by '\t';
6、修改分割符
ALTER TABLE 表名 [partition(分区字段[='202103')]] SET SERDEPROPERTIES (‘field.delim’ = ‘,’ , ‘serialization.format’=’,’);
7、并发执行insert overwrite table
场景:要向一个表的多个分区写数据,为缩短时间,采用并发多个sql同时执行,分别写入不同分区,同时开启了动态分区:
set hive.exec.dynamic.partition=true
insert overwrite table test_table partition(dt) select * from test where dt=1
结果:只有一个sql运行,其他都会卡住
原因:开启动态分区时,锁的粒度是DbName + TableName,这样就会导致多个sql只有1个sql可以拿到lock,其他的sql只能等待
解决:
1、关闭动态分区:set hive.exec.dynamic.partition=false
2、关闭并发:set hive.support.concurrency=false
3、关闭事务:set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager
区:set hive.exec.dynamic.partition=false
2、关闭并发:set hive.support.concurrency=false
3、关闭事务:set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager