精华内容
下载资源
问答
  • HIVE动态分区插入数据

    2017-04-21 16:00:00
    Hive的insert语句能够从查询语句中获取数据,并同时将数据Load到目标表中。现在假定有一个已有数据的表staged_employees(雇员信息全量表),所属国家cnty和所属州st是该表的两个属性,我们做个试验将该表中的数据...

     Hive的insert语句能够从查询语句中获取数据,并同时将数据Load到目标表中。现在假定有一个已有数据的表staged_employees(雇员信息全量表),所属国家cnty和所属州st是该表的两个属性,我们做个试验将该表中的数据查询出来插入到另一个表employees中。

    1

    2

    3

    4

    INSERT OVERWRITE TABLE employees

    PARTITION (country = '中国', state = '北京')

    SELECT * FROM staged_employees se

    WHERE se.cnty = '中国' AND se.st = '北京';

    由于使用了OVERWRITE关键字,目标表中原来相同partition中的所有数据被覆盖,如果目标表中没有partition,则整个表会被覆盖。

    如果把OVERWRITE关键字删掉,或者替换成INTO,则hive会追加而不是替代原分区或原表中的数据,这个特性在Hive v0.8.0之后才支持。

    当数据已经存在于hdfs上但不是我们想要的格式的时候,当进行的计算需要分好多步骤有必要存储中间数据的时候,或者原数据没有分区、有很多无效列需要过滤的时候,可以使用insert..select句型来完成这一转换过程。

    由于一个国家有很多个省份,如果想根据(国家country,地区partition)两个维度对数据进行分区的话,这条SQL语句的执行个数应该等于地区的数目,比如中国有23个省就要对该SQL语句执行23次。因此hive对这个SQL语句进行了改造,只需要扫描一次原表就可以生成不同的输出(多路输出)。比如下面的SQL语句扫描了一次原始数据表,但是同时生成了3个省份的结果数据:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    FROM staged_employees se

    INSERT OVERWRITE TABLE employees

    PARTITION (country = '中国', state = '河北省')

    SELECT * WHERE se.cnty = '中国' AND se.st = '河北省'

    INSERT OVERWRITE TABLE employees

    PARTITION (country = '中国', state = '陕西省')

    SELECT * WHERE se.cnty = '中国' AND se.st = '陕西省'

    INSERT OVERWRITE TABLE employees

    PARTITION (country = '中国', state = '河南省')

    SELECT * WHERE se.cnty = 'US' AND se.st = '河南省';

    通过缩进可以很清楚的看到,我们扫描了一次staged_employees表但是执行了3次不同的insert语句,这条大SQL语句是这么执行的:先通过from staged_employees表获取一条记录,然后执行每一个select子句,如果select子句验证通过则执行相应的insert语句。注意这里的三条select子句是完全独立执行的,并不是if .. then .. else的关系,这就意味着这3条select子句在某种情况下可能同时通过where检测。

    通过这种结构,原始表的数据能被拆分到目标表的不同partition中去。

    如果原表的一条记录满足于其中一个给定的select .. where .. 子句,则该记录将被写到目标表的固定分区中。其实更进一步,每条Insert语句能将数据写到不同的数据表中,不管这个表是否分区都一样。

    于是,就像一个过滤器一样,原表的一些数据被写到了很多输出地址,而剩下的数据会被丢弃。

    当然,你也可以混用Insert overwrite和insert into两种不同的方法写出数据。

    向动态分区插入数据

    但是问题还是没有解决,中国有23个省,那么我们就需要写23个insert into .. select ..where子句,这非常不现实。于是hive的一种叫做动态分区的特性就出现了,它能够根据select出来的参数自动推断将数据插入到那个分区中去。本文上面的两种SQL语句设定分区的方式都叫做静态分区插入。

    将上一个SQL语句进行改动,会得到以下简洁的新SQL语句:

    1

    2

    3

    4

    INSERT OVERWRITE TABLE employees

    PARTITION (country, state)

    SELECT ..., se.cnty, se.st

    FROM staged_employees se;

    hive先获取select的最后两个位置的se.cnty和se.st参数值,然后将这两个值填写到Insert语句partition中的两个country和state变量中,即动态分区是通过位置来对应分区值的。原始表select出来的值和输出partition的值的关系仅仅是通过位置来确定的,和名字并没有关系,比如这里se.cnty和county的名称完全没有关系。

    上面的这条SQL语句是对两个分区同时进行了动态设定,如果staged_employees表中有100个国家,每个国家有100个地区,那么该SQL语句自动对每个国家和地区建立相应的partition并插入数据,如果用手写的话不现实。

    只要位置正确,你可以混用动态分区和静态分区值设定,比如下面这个例子,你可以静态指定一个country值,但是state值采用动态的方法设定:

    1

    2

    3

    4

    5

    INSERT OVERWRITE TABLE employees

    PARTITION (country = 'US', state)

    SELECT ..., se.cnty, se.st

    FROM staged_employees se

    WHERE se.cnty = 'US';

    注意:静态分区值必须在动态分区值的前面!

    使用hive动态分区的参数设定

    动态分区功能默认是关闭的,而当它是打开状态时,默认会工作在“strict”模式下,这种模式下要求至少指定一个静态分区的值。这样做是为了防止设计了大量partition的糟糕情况,举个例子你使用时间戳来进行分区,竟然每一秒钟都产生一个分区!还有其他的一些属性设定用来限制类似的情况出现,如下表所示:

    名称默认值描述
    hive.exec.dynamic.partitionfalse设置为true用于打开动态分区功能
    hive.exec.dynamic.partition.modestrict设置为nonstrict能够让所有的分区都动态被设定,否则的话至少需要指定一个分区值
    hive.exec.max.dynamic.partitions.pernode100能被每个mapper或者reducer创建的最大动态分区的数目,如果一个mappre或者reducer试图创建多余这个值的动态分区数目,会引发错误
    hive.exec.max.dynamic.partitions+1000被一条带有动态分区的SQL语句所能创建的动态分区总量,如果超出限制会报出错误
    hive.exec.max.created.files100000全局能被创建文件数目的最大值,专门有一个hadoop计数器来跟踪该值,如果超出会报错

    举个例子,使用全动态分区的SQL语句序列如下所示,需要先设定一些必要的参数才可以:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    set hive.exec.dynamic.partition=true;

    set hive.exec.dynamic.partition.mode=nonstrict;

    set hive.exec.max.dynamic.partitions.pernode=1000;

    INSERT OVERWRITE TABLE employees

    PARTITION (country, state)

    SELECT ..., se.cty, se.st

    FROM staged_employees se;

    总结

    使用from .. insert.. select ..where结构能够从一个数据表中抽取数据,将结果插入到不同的表和分区中,而使用动态分区能够让hive根据select最末几个位置的值自动设定目标分区的值,使用动态分区需要设定一些hive运行参数。

     

    转载于:https://my.oschina.net/Yghost/blog/884469

    展开全文
  • hive 动态分区插入数据表 set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; set hive.exec.max.dynamic.partitions.pernode=2000; set hive.exec.max.dynamic.partitions=...

    hive 动态分区插入数据表
    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    set hive.exec.max.dynamic.partitions.pernode=2000;
    set hive.exec.max.dynamic.partitions=2000;
    set hive.optimize.sort.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    insert into table_name PARTITION(dt)
    select
    a,
    b,
    c,
    d,
    dt
    from table_name2

    展开全文
  • Hive 动态分区插入数据总结 1、问题描述 执行以下sql导致reduce端OOM,分区数有485个按天分区,数据主要是存量数据一次性导入数仓中遇到的问题。 服务器 :8核12G内存 Map内存参数值: mapreduce.map.memory.mb...

    Hive 动态分区插入数据总结

    1、问题描述

    执行以下sql导致reduce端OOM,分区数有485个按天分区,数据主要是存量数据一次性导入数仓中遇到的问题。

    服务器 :8核12G内存

    Map内存参数值:

    mapreduce.map.memory.mb=1024

    mapreduce.map.java.opts=-Xmx768m -XX:+UseConcMarkSweepGC;

    Reduce内存参数值:

    mapreduce.reduce.memory.mb=2048

    mapreduce.reduce.java.opts=-Xmx1536m -XX:+UseConcMarkSweepGC;

    展开全文
  • Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:157) at...

    Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row
    at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:157)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:465)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:349)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1875)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:168)
    Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while proces

    Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row
    at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:157)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:465)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:349)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1875)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:168)
    Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row
    at org.apache.hadoop.hive.ql.exec.vector.VectorMapOperator.process(VectorMapOperator.java:879)
    at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:148)
    … 8 more
    Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: [Error 20004]: Fatal error occurred when node tried to create too many dynamic partitions.
    The maximum number of dynamic partitions is controlled by hive.exec.max.dynamic.partitions and hive.exec.max.dynamic.partitions.pernode.
    Maximum was set to 100 partitions per node, number of dynamic partitions on this node: 101

    at org.apache.hadoop.hive.ql.exec.FileSinkOperator.getDynOutPaths(FileSinkOperator.java:951)
    at org.apache.hadoop.hive.ql.exec.FileSinkOperator.process(FileSinkOperator.java:722)
    at org.apache.hadoop.hive.ql.exec.vector.VectorFileSinkOperator.process(VectorFileSinkOperator.java:101)
    at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:882)
    at org.apache.hadoop.hive.ql.exec.vector.VectorSelectOperator.process(VectorSelectOperator.java:137)
    at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:882)
    at org.apache.hadoop.hive.ql.exec.TableScanOperator.process(TableScanOperator.java:130)
    at org.apache.hadoop.hive.ql.exec.vector.VectorMapOperator.process(VectorMapOperator.java:779)
    … 9 more

    原因:
    这是因为hive在自动创建分区的时候,最大的分区数是100,而任务执行超过了这个数,需要手动设置。

    解决办法:
    手动设置动态分区的最大分区数 和 每个节点数

    hive > set hive.exec.max.dynamic.partitions = 100000; 
    hive > set hive.exec.max.dynamic.partitions.pernode = 100000; 
    

    重新执行导入即可成功。


    另外补充,设置动态分区的严格模式参数:

    hive > set hive.exec.dynamic.partition = true;
    hive > set hive.exec.dynamic.partition = nonstrict;
    
    展开全文
  • hive上建表与普通分区表创建方法一样; 1 CREATE TABLE `dwa_m_user_association_circle`( 2 `device_number` string, 3 `oppo_number` string, 4 `prov_id_oppo` string, 5 `area_id_oppo` string...
  • 【hive创建动态分区】hive使用动态分区插入数据详解 往hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以...
  • hive使用动态分区插入数据详解

    万次阅读 多人点赞 2018-05-20 15:21:57
    hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以hive提供了一个动态分区功能,其可以基于查询参数的...
  • hive动态分区插入

    2019-06-16 18:14:13
    动态分区插入(即多分区插入)旨在通过在扫描输入表时动态确定应该创建和填充的分区来解决此问题。该功能仅适用于0.6.0及以上版本。在动态分区插入中,将评估输入列值以确定应该将该行插入哪个分区。该分区如果尚未...
  • hive动态分区插入实验

    千次阅读 2016-03-07 11:15:48
    1. 验证对分区表进行动态分区插入功能 2. 验证是否可以使用load进行动态分区插入 实验步骤 1. 在本地文件/home/grid/a.txt中写入以下4行数据: aaa,US,CA aaa,US,CB bbb,CA,BB bbb,CA,BC 2. 建立非分区...
  • 今天需要将一个分区表的数据(A)迁移到另一张表(B),两个表的字段不完全一样,但是分区一样,要求迁入到B表后,原来的数据还在原来的分区里,和原来一一对应,表结构如下: A:B: A表的分区: 由于分区比较多,一...
  • hive使用动态分区插入数据详解 往hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以hive提供了一个动态分区...
  • hive动态分区插入数据

    千次阅读 2017-10-11 14:07:39
    向一个定义了分区的空表中插入数据,命令如下:insert overwrite table t_name partition (par_1) select t1.field1 as field1, t1.field2 as field2, t1.field3 as par_1 from ( select * from t3 where par_2=...
  • Spark 调用 hive使用动态分区插入数据

    万次阅读 2019-07-24 17:11:39
    spark 调用sql插入hive 失败 ,执行语句如下 spark.sql("INSERT INTO default.test_table_partition partition(province,city) SELECT xxx,xxx md5(province),md...报错如下,需动态插入分区 Exception in thre...
  • 静态分区插入时对分区字段指定值,动态分区插入时对分区字段不指定值 动态分区可以通过下面的设置来打开: set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; 然后...
  • 首先列举下hive分区插入的方式: 1:从文件导入数据到hive指定分区方式 load data local inpath ‘filepath’ into table tableName partition(partitionColumn=’’); 2:先创建分区,再把文件通过任何别的方式把...
  • 4.多个分区字段时,全部实现动态分区插入数据 set hive.exec.dynamici.partition= true ; set hive.exec.dynamic.partition.mode=nonstrict; insert overwrite table ds_parttion partition (state,ct)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,496
精华内容 4,998
关键字:

hive动态分区插入数据