【大数据哔哔集20210113】Hive的动态分区和静态分区

2021-01-21 19:17:10 浏览数 (1)

Hive中支持两种模式的分区:

•静态分区SP(static partition)

•动态分区DP(dynamic partition)

静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在SQL执行时才能决定。不难看出,Hive分区主要是以缩小数据查询范围,提高查询速度和性能的。

动态分区在默认情况下是禁用的(在hive2.3.4版本中默认是开启的,可以在hive-default.xml.template文件中进行配置),所以需要将hive.exec.dynamic.partition设为true。默认情况下,用户必须至少指定一个静态分区列,这是为了避免意外覆盖分区。要禁用此限制,可以设置分区模式为非严格模式(即将hive.exec.dynamic.partition.mode设为nonstrict,默认值为strict)。可以选择在命令行终端方式设置:

代码语言:javascript复制
SET hive.exec.dynamic.partition=true;
SET hive.exec.dynamic.partition.mode=nonstrict;

或者你可以在hive-site.xml中这样设置:

-- Hive默认配置值-- 开启或关闭动态分区hive.exec.dynamic.partition=false;-- 设置为nonstrict模式,让所有分区都动态配置,否则至少需要指定一个分区值hive.exec.dynamic.partition.mode=strict;-- 能被mapper或reducer创建的最大动态分区数,超出而报错hive.exec.max.dynamic.partitions.pernode=100;-- 一条带有动态分区SQL语句所能创建的最大动态分区总数,超过则报错hive.exec.max.dynamic.partitions=1000;-- 全局能被创建文件数目的最大值,通过Hadoop计数器跟踪,若超过则报错hive.exec.max.created.files=100000; -- 根据个人需要配置set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict;set hive.exec.max.dynamic.partitions.pernode=1000;set hive.exec.max.dynamic.partitions=10000;set hive.exec.max.created.files=1000000;

实战演示

首先我们创建一个表,并导入相关数据,作为源数据。

代码语言:javascript复制
CREATE TABLE student_data(id STRING, name STRING, year INT, major INT) 
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',';

静态分区

创建一个表,用静态分区方式将数据导入此表。

代码语言:javascript复制
CREATE TABLE student_static_partition(id STRING, name STRING) 
PARTITIONED BY (year INT, major INT)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',';

使用静态分区方式,将源表中的所有数据导入此表:

代码语言:javascript复制
INSERT INTO TABLE student_static_partition PARTITION(year=2001,major=810) 
SELECT id,name FROM student_data WHERE year=2001 AND major=810;

INSERT INTO TABLE student_static_partition PARTITION(year=2001,major=820) 
SELECT id,name FROM student_data WHERE year=2001 AND major=820;

INSERT INTO TABLE student_static_partition PARTITION(year=2002,major=810) 
SELECT id,name FROM student_data WHERE year=2002 AND major=810;

INSERT INTO TABLE student_static_partition PARTITION(year=2002,major=820) 
SELECT id,name FROM student_data WHERE year=2002 AND major=820;

导完后,查询该表的分区信息:

代码语言:javascript复制
SHOW PARTITIONS student_static_partition;
 ---------------------- -- 
|      partition       |
 ---------------------- -- 
| year=2001/major=810  |
| year=2001/major=820  |
| year=2002/major=810  |
| year=2002/major=820  |
 ---------------------- -- 

动态分区

再创建一个相同表结构的表,准备以动态分区的方式导入数据。

代码语言:javascript复制
CREATE TABLE student_dynamic_partition(id STRING, name STRING) 
PARTITIONED BY (year INT, major INT)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',';

使用动态分区前,需要先配置相同的Hive参数,其中最重要的两个参数是:

代码语言:javascript复制
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;

然后以动态分区方式导入数据:

代码语言:javascript复制
INSERT OVERWRITE TABLE student_dynamic_partition PARTITION (year, major) 
SELECT id,name,year,major 
FROM student_data;

注意:在SELECT子句的各个字段应刚好与INSERT中的字段以及最后的PARTITION中的字段完全一致,包括顺序。

这里,我们无需指定数据导入到哪一个分区。该语句会自动创建相应分区,并将数据导入相应的分区。

导入完成后,查看该表的分区信息:

代码语言:javascript复制
SHOW PARTITIONS student_dynamic_partition
 ---------------------- -- 
|      partition       |
 ---------------------- -- 
| year=2001/major=810  |
| year=2001/major=820  |
| year=2002/major=810  |
| year=2002/major=820  |
 ---------------------- -- 

与动态分区相关的一些参数如下:

代码语言:javascript复制
-- Hive默认配置值
-- 开启或关闭动态分区
hive.exec.dynamic.partition=false;
-- 设置为nonstrict模式,让所有分区都动态配置,否则至少需要指定一个分区值
hive.exec.dynamic.partition.mode=strict;
-- 能被mapper或reducer创建的最大动态分区数,超出而报错
hive.exec.max.dynamic.partitions.pernode=100;
-- 一条带有动态分区SQL语句所能创建的最大动态分区总数,超过则报错
hive.exec.max.dynamic.partitions=1000;
-- 全局能被创建文件数目的最大值,通过Hadoop计数器跟踪,若超过则报错
hive.exec.max.created.files=100000;

-- 根据个人需要配置
set hive.exec.dynamic.partition=true;  
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions.pernode=1000;
set hive.exec.max.dynamic.partitions=10000;
set hive.exec.max.created.files=1000000;

0 人点赞