赞
踩
目录
1) 引入分区表(需要根据日期对日志进行管理,通过部门信息模拟)
Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录,每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区,这样的查询效率会提高很多。
将一张大表按照某个字段进行划分 划分到多个文件夹中 每个文件夹内部存储一部分表内容 这样的表结构就被称之为分区表
分区的好处:
1. 方便数据管理
2. 加快查询效率 不再执行过滤操作
- dept_20200401.log
- dept_20200402.log
- dept_20200403.log
2) 创建分区表语法
- create table dept_partition(
- deptno int,
- dname string,
- loc string)
- partitioned by (day string)
- row format delimited fields terminated by '\t';
注意:分区字段不能是表中已经存在的数据,可以将分区字段看作表的伪列。
(1) 数据准备
dept_20200401.log
- 10 ACCOUNTING 1700
- 20 RESEARCH 1800
dept_20200402.log
- 30 SALES 1900
- 40 OPERATIONS 1700
dept_20200403.log
- 50 TEST 2000
- 60 DEV1 900
(2) 加载数据
- load data local inpath '/opt/apps/hive/datas/dept_20200401.log' into table dept_partition partition(day='20200401');
-
- load data local inpath '/opt/apps/hive/datas/dept_20200402.log' into table dept_partition partition(day='20200402');
-
- load data local inpath '/opt/apps/hive/datas/dept_20200403.log' into table dept_partition partition(day='20200403');
注意:分区表加载数据时,必须指定分区
单分区查询
select * from dept_partition where day='20200401';
多分区联合查询
- select * from dept_partition where day='20200401'
- union
- select * from dept_partition where day='20200402'
- union
- select * from dept_partition where day='20200403';
-
- select * from dept_partition where day='20200401' or day='20200402' or day='20200403';
创建单个分区
alter table dept_partition add partition(day='20200404');
同时创建多个分区
alter table dept_partition add partition(day='20200405') partition(day='20200406');
删除单个分区
alter table dept_partition drop partition (day='20200406');
同时删除多个分区
alter table dept_partition drop partition (day='20200404'), partition(day='20200405');
hive> show partitions dept_partition;
data_typehive> desc formatted dept_partition;
Hive将分区表的所有分区信息都保存在了元数据中,只有元数据与HDFS上的分区路径一致时,分区表才能正常读写数据。
若用户手动创建/删除分区路径,Hive都是感知不到的,这样就会导致Hive的元数据和HDFS的分区路径不一致。
再比如,若分区表为外部表,用户执行drop partition命令后,分区元数据会被删除,而HDFS的分区路径不会被删除,同样会导致Hive的元数据和HDFS的分区路径不一致。
Add partition
若手动创建HDFS的分区路径,Hive无法识别,可通过add partition命令增加分区元数据信息,从而使元数据和分区路径保持一致。
Drop partition
若手动删HDFS的分区路径,Hive无法识别,可通过drop partiton命令删除分区元数据信息,从而使元数据和分区路径保持一致。
msck(MetaStore check)
若分区元数据和HDFS的分区路径不一致,还可使用msck命令进行修复,以下是该命令的用法说明。
- msck repair table table_name [add/drop/sync partition]
-
- --该命令会增加HDFS路径存在但元数据缺失的分区信息
- msck repair table table_name add partition
-
- --该命令会删除HDFS路径存在但元数据缺失的分区信息
- msck repair table table_name drop partition
-
- --该命令会同步HDFS路径和元数据分区信息,相当于同时执行上述的两个命令
- msck repair table table_name sync partition
-
- msck repari table table_name等价于msck repair table table_name add partitions命令
思考: 如何一天的日志数据量也很大,如何再将数据拆分?
1) 创建二级分区表
- create table dept_partition2(
- deptno int,
- dname string,
- loc string)
- partitioned by (day string, hour string)
- row format delimited fields terminated by '\t';
2) 正常的加载数据
(1) 加载数据到二级分区表中
load data local inpath '/opt/apps/hive/datas/dept_20200401.log' into table dept_partition2 partition(day='20200401', hour='12');
(2) 查询分区数据
select * from dept_partition2 where day='20200401' and hour='12';
3) 把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式
(1) 方式一:上传数据后修复
上传数据
- dfs -mkdir -p /user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=13;
-
- dfs -put /opt/apps/datas/dept_20200401.log /user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=13;
查询数据(查询不到刚上传的数据)
select * from dept_partition2 where day='20200401' and hour='13';
执行修复命令
msck repair table dept_partition2;
再次查询数据
select * from dept_partition2 where day='20200401' and hour='13';
(2) 方式二:上传数据后添加分区
上传数据
- dfs -mkdir -p /user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=14;
-
- dfs -put /opt/apps/hive/datas/dept_20200401.log /user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=14;
执行添加分区
alter table dept_partition2 add partition(day='201709',hour='14');
查询数据
select * from dept_partition2 where day='20200401' and hour='14';
(3) 方式三:创建文件夹后 load 数据到分区
创建目录
dfs -mkdir -p /user/hive/warehouse/mydb.db/dept_partition2/day=20200401/hour=15;
上传数据
load data local inpath '/opt/apps/hive/datas/dept_20200401.log' into table dept_partition2 partition(day='20200401',hour='15');
查询数据
select * from dept_partition2 where day='20200401' and hour='15';
关系型数据库中,对分区表 Insert 数据时,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive 中也提供了类似的机制,即动态分区(Dynamic Partition),只不过,使用 Hive 的动态分区,需要进行相应的配置。
1) 开启动态分区参数设置
(1) 开启动态分区功能(默认true,开启)
set hive.exec.dynamic.partition=true
(2)设置为非严格模式(动态分区的模式,默认 strict,表示必须指定至少一个分区为静态分区,nonstrict 模式表示允许所有的分区字段都可以使用动态分区。)
set hive.exec.dynamic.partition.mode=nonstrict
(3) 在所有执行 MR 的节点上,最大一共可以创建多少个动态分区。默认 1000
set hive.exec.max.dynamic.partitions=1000
(4) 在每个执行 MR 的节点上,最大可以创建多少个动态分区。该参数需要根据实际的数据来设定。比如:源数据中包含了一年的数据,即 day 字段有 365 个值,那么该参数就需要设置成大于 365,如果使用默认值 100,则会报错。
set hive.exec.max.dynamic.partitions.pernode=100
(5)整个 MR Job 中,最大可以创建多少个 HDFS 文件。默认 100000
set hive.exec.max.created.files=100000
(6) 当有空分区生成时,是否抛出异常。一般不需要设置。默认 false
set hive.error.on.empty.partition=false
2) 案例实操
需求:将 dept 表中的数据按照地区(loc 字段),插入到目标表 dept_partition 的相应分区中。
(1) 创建目标分区表
create table dept_partition_dy(id int, name string) partitioned by (loc int) row format delimited fields terminated by '\t';
(2) 设置动态分区
- set hive.exec.dynamic.partition.mode = nonstrict;
-
- insert into table dept_partition_dy partition(loc) select deptno, dname, loc from dept;
(3) 查看目标分区表的分区情况
show partitions dept_partition;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。