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

Meo*_*ehr 7 hadoop hive acid emr 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

如果您想使用合并进行更新插入,那么您必须在托管配置单元内部表中拥有数据,如果您不想复制文件,这是简单的解决方案

  1. 创建类似结构的内表

    创建表 table1( id int, Name string,
    UpdatedDate date ) 由 (id) 聚集到存储为 ORC 的 2 个桶中 tblproperties("transactional"="true","skip.header.line.count"="1");

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

    INSERT INTO TABLE table1 SELECT * FROM 外部表;

  3. 运行合并语句来更新内表

    设置 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; 使用 DailyFeed on DailyFeed.id= table1.id(匹配时)和 table1.name<>DailyFeed.name 合并到 table1,然后更新 set name= DailyFeed.name(不匹配时)然后插入值 (DailyFeed.id, DailyFeed.name, CURRENT_DATE) ;

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

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

或者

insert overwrite local directory '/home/user1/table1.csv' row format delimited fields terminated by ',' SELECT * FROM table1;
Run Code Online (Sandbox Code Playgroud)

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

谢谢

尼勒什