zoukankan      html  css  js  c++  java
  • Hive的静态分区和动态分区

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl/p/6831884.html 转载请注明出处

    虽然之前已经用过很多次hive的分区表,但是还是找时间快速回顾总结一下加深理解.

    举个栗子,基本需求就是Hive有一张非常详细的原子数据表original_device_open,而且还在不断随着时间增长,那么我需要给它进行分区,为什么要分区?因为我想缩小查询范围,提高速度和性能.

    分区其实是物理上对hdfs不同目录进行数据的load操作,0.7之后的版本都会自动创建不存在的hdfs的目录,不同的目录对应不同的分区字段,当然会有一个处于最顶层的主分区字段.

    我这里的分区字段主要是时间,分为年,月,日,时

    首先建立一个新的分区表(这里我不在原始数据表直接操作)

    CREATE TABLE device_open (
    deviceid varchar(50),
    ...
    )
    PARTITIONED BY (year varchar(50),month varchar(50),day varchar(50),hour varchar(50))
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '	';

    然后我要从原始表中select数据插入到新建的分区表中去,如下采用动态插入(…代表省略的字段)

    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    insert overwrite table device_open partition(year,month,day,hour)
    select
    ...,
    original_device_open.year as year,
    original_device_open.month as month,
    original_device_open.day as day,
    original_device_open.hour as hour
    FROM original_device_open

    简单解释下

    set hive.exec.dynamic.partition=true; 是开启动态分区

    set hive.exec.dynamic.partition.mode=nonstrict; 这个属性默认值是strict,就是要求分区字段必须有一个是静态的分区值,随后会讲到,当前设置为nonstrict,那么可以全部动态分区

    其他相关属性见下表

    hivePartitionParams

    注意代码中标红的部分,partition(year,month,day,hour) 就是要动态插入的分区.

    代码执行后一直卡在map百分比90%处,然后重试了都失败,查看后发现如下日志

    Fatal error occurred when node tried to create too many dynamic partitions.

    hiveDynamic

     

    很明显的错误,太多动态分区了,因为 hive.exec.max.dynamic.partitions默认值是1000,而我这里的分区我确定肯定超过这个值了,那么修改如下

    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    SET hive.exec.max.dynamic.partitions=100000;
    SET hive.exec.max.dynamic.partitions.pernode=100000;

    重新执行insert分区代码,插入成功.

    当然,对于大批量数据的插入分区,动态分区相当方便,对于小批量的分区插入,比如想定时每天执行某个时间段的分区数据插入,那也很简单,如下代码

    insert overwrite table device_open partition(year='2017',month='05',day,hour)
    select
    ...,
    original_device_open.day as day,
    original_device_open.hour as hour
    FROM original_device_open where original_device_open.year='2017' and original_device_open.month='05'

    注意 partition(year='2017',month='05',day,hour)

    我只需要指明需要静态分区的字段值就可以.剩下的字段就属于动态分区了,这里指将2017年5月份的数据插入分区表,对应底层的物理操作就是讲2017年5月份的数据load到

    hdfs上对应2017年5月份下的所有day和hour目录中去.

  • 相关阅读:
    leetcode_138复制带随机指针的链表
    minSTL
    LLVM
    STL基础_迭代器
    mysql数据库表清空后id如何从1开始自增
    explain用法和结果分析
    MySQL多表查询与子查询
    数据结构与算法笔记
    MySQL数据库的SQL语言与视图
    mysql忘记密码解决方案
  • 原文地址:https://www.cnblogs.com/cssdongl/p/6831884.html
Copyright © 2011-2022 走看看