使用hive的合并语句将delta数据合并到外部表

时间:2018-01-02 13:07:18

标签: hadoop hive emr acid orc

我在Hive(EMR-5.11.0上的v2.3.2)中映射了一个外部表,我需要每周更新一次新数据。合并由条件upsert语句组成。

表的位置在s3中,数据始终存在(创建一次,我们只需要用新数据更新它)。

我已经阅读了这篇关于在事务表(https://dzone.com/articles/update-hive-tables-the-easy-way-part-2-hortonworks)上使用ACID功能在Hive中合并数据的博客,但据我所知,唯一的解决方案是将我的外部表复制到临时Hive内部表,即集群和事务性的,然后只在该表上我可以进行合并并使用新合并的表覆盖原始数据。

这个表非常大(大约10GB的数据),所以我想避免在每次合并操作之前复制它。

有没有办法创建内部表并将其映射到现有数据?还是有另一种方法,除了合并语句,在Hive外部表上执行upsert?

提前多多感谢!

1 个答案:

答案 0 :(得分:1)

如果要对合并使用合并,则必须在托管配置单元内部表中保存数据,如果不想复制文件,则可以采用简单的解决方案

  1. 创建类似结构的内部表

    创建表table1(     id int,     名称字符串,
        更新日期 ) 由(id)聚集成存储为ORC的2个存储桶 tblproperties(“ transactional” =“ true”,“ skip.header.line.count” =“ 1”);

  2. 将数据从外部表插入内部表

    插入表table1 从您的外部表中选择*;

  3. 运行您的merge语句以更新内部表

    set hive.support.concurrency = true; 设置hive.enforce.bucketing = true; 设置hive.exec.dynamic.partition.mode = nonstrict; 设置hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; 设置hive.compactor.initiator.on = true; 设置hive.compactor.worker.threads = 1; 合并成 表格1 使用  DailyFeed 上  DailyFeed.id = table1.id 与table1.name <> DailyFeed.name匹配时 然后  更新集名称= DailyFeed.name 当不匹配时  插入值(DailyFeed.id,DailyFeed.name,CURRENT_DATE)  ;

  4. 覆盖基本文件导出内部表

hive -e'设置hive.cli.print.header = true;从表1中选择* sed's / [[:: space:]] + /,/ g'> /home/user1/table1.csv

insert overwrite local directory '/home/user1/table1.csv' row format delimited fields terminated by ',' SELECT * FROM table1;

希望这将有助于解决您的问题

谢谢

尼罗什