需求场景:hive计算完成导入oracle以后由于结果表需要重建,需要把hive中保存的分区信息同步到另外一张hive表对应的分区中,就涉及到多分区同时插入,下面介绍方法。

Hive中是支持分区的。

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

先看一个应用场景,源表t_lxw1234的数据如下:

 


    1. 
    2. SELECT day,url FROM t_lxw1234;
    3. 2015-05-10      url1
    4. 2015-05-10      url2
    5. 2015-06-14      url1
    6. 2015-06-14      url2
    7. 2015-06-15      url1
    8. 2015-06-15      url2
    9. ……
    10.


     

    目标表为:

    1. 
    2. CREATE TABLE t_lxw1234_partitioned (
    3. url STRING
    4. ) PARTITIONED BY (month STRING,day STRING) 
    5. stored AS textfile;
    6.

    需求:将t_lxw1234中的数据按照时间(day),插入到目标表t_lxw1234_partitioned的相应分区中。

    如果按照之前介绍的往指定一个分区中Insert数据,那么这个需求很不容易实现。

    这时候就需要使用动态分区来实现,使用动态分区需要注意设定以下参数:

    • 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

    当有空分区生成时,是否抛出异常。

    一般不需要设置。

     

    那么,上面的需求可以使用如下的语句来完成:

    1. 
    2. SET hive.exec.dynamic.partition=true;  
    3. SET hive.exec.dynamic.partition.mode=nonstrict; 
    4. SET hive.exec.max.dynamic.partitions.pernode = 1000;
    5. SET hive.exec.max.dynamic.partitions=1000;
    6.  
    7. INSERT overwrite TABLE t_lxw1234_partitioned PARTITION (month,day) 
    8. SELECT url,substr(day,1,7) AS month,day 
    9. FROM t_lxw1234;
    10.  
     
    PARTITION (month,day)中指定分区字段名即可;
    PARTITION (month,day)中指定的分区字段,包括顺序。
     执行结果如下:
     Loading data to table liuxiaowen.t_lxw1234_partitioned partition (month=null, day=null)
     Loading partition {month=2015-05, day=2015-05-10}
     Loading partition {month=2015-06, day=2015-06-14}
     Loading partition {month=2015-06, day=2015-06-15}
     Partition liuxiaowen.t_lxw1234_partitioned{month=2015-05, day=2015-05-10} stats: [numFiles=1, numRows=2, totalSize=10, rawDataSize=8]
     Partition liuxiaowen.t_lxw1234_partitioned{month=2015-06, day=2015-06-14} stats: [numFiles=1, numRows=2, totalSize=10, rawDataSize=8]
     Partition liuxiaowen.t_lxw1234_partitioned{month=2015-06, day=2015-06-15} stats: [numFiles=1, numRows=2, totalSize=10, rawDataSize=8]
      
     使用show partitions t_lxw1234_partitioned;查看目标表有哪些分区:
     hive> show partitions t_lxw1234_partitioned;
     OK
     month=2015-05/day=2015-05-10
     month=2015-06/day=2015-06-14
     month=2015-06/day=2015-06-15