动态分区说明

Hive分区

Hive的动态分区

概述

hive中支持两种类型的分区:

  • 静态分区SP(static partition)
  • 动态分区DP(dynamic partition)

静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在SQL执行时才能决定。

动态分区说明

关系型数据库(如Oracle)中,对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive中也提供了类似的机制,即动态分区(Dynamic Partition),只不过,使用Hive的动态分区,需要进行相应的配置。

按照常规的方法向分区表中插入数据,如果源数据量很大,那么针对一个分区就要写一个insert,非常麻烦,你必须先要知道源数据中都有什么样的数据才能创建分区。
例如:

1
hive> insert overwrite table partition_test partition(stat_date='20110728',province='henan') select member_id,name from partition_test_input where stat_date='20110728' and province='henan';

使用动态分区可以很好的解决上述问题。动态分区可以根据查询得到的数据自动匹配到相应的分区中去。
使用动态分区要先设置hive.exec.dynamic.partition参数值为true,默认值为false,即不允许使用:

1
2
3
4
5
hive> set hive.exec.dynamic.partition;
hive.exec.dynamic.partition=false
hive> set hive.exec.dynamic.partition=true;
hive> set hive.exec.dynamic.partition;
hive.exec.dynamic.partition=true

动态分区的使用方法很简单,假设我想向stat_date=’20110728’这个分区下面插入数据,至于province插入到哪个子分区下面让数据库自己来判断,那可以这样写:

1
2
3
4
5
6
hive> insert overwrite table partition_test partition(stat_date='20110728',province)
> select member_id,name,province from partition_test_input where stat_date='20110728';
Total MapReduce jobs = 2
...
3 Rows loaded to partition_test
OK

stat_date叫做静态分区列,province叫做动态分区列。select子句中需要把动态分区列按照分区的顺序写出来,静态分区列不用写出来。这样stat_date=’20110728’的所有数据,会根据province的不同分别插入到/user/hive/warehouse/partition_test/stat_date=20110728/下面的不同的子文件夹下,如果源数据对应的province子分区不存在,则会自动创建,非常方便,而且避免了人工控制插入数据与分区的映射关系存在的潜在风险。

  • 注意,动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区
  • 动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数hive.exec.dynamic.partition.mode :
    1
    2
    hive> set hive.exec.dynamic.partition.mode;
    hive.exec.dynamic.partition.mode=strict

动态分区demo

1
2
3
4
5
6
7
8
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=1000;

INSERT overwrite TABLE t_lxw1234_partitioned PARTITION (month,day)
SELECT url,substr(day,1,7) AS month,day
FROM t_lxw1234;

动态分区参数

使用动态分区需要注意设定以下参数:

  • hive.exec.dynamic.partition
    默认值:false
    是否开启动态分区功能,默认false关闭。
    使用动态分区时候,该参数必须设置成true;

  • hive.exec.dynamic.partition.mode
    默认值:strict
    动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。
    一般需要设置为nonstrict

  • hive.exec.max.dynamic.partitions.pernode
    默认值:100
    在每个执行MR的节点上,最大可以创建多少个动态分区。
    该参数需要根据实际的数据来设定。
    比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错。

  • hive.exec.max.dynamic.partitions
    默认值:1000
    在所有执行MR的节点上,最大一共可以创建多少个动态分区。
    同上参数解释。

  • hive.exec.max.created.files
    默认值:100000
    整个MR Job中,最大可以创建多少个HDFS文件。
    一般默认值足够了,除非你的数据量非常大,需要创建的文件数大于100000,可根据实际情况加以调整。

  • hive.error.on.empty.partition
    默认值:false
    当有空分区生成时,是否抛出异常。
    一般不需要设置。