我在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?
提前多多感谢!
答案 0 :(得分:1)
如果要对合并使用合并,则必须在托管配置单元内部表中保存数据,如果不想复制文件,则可以采用简单的解决方案
创建类似结构的内部表
创建表table1(
id int,
名称字符串,
更新日期
)
由(id)聚集成存储为ORC的2个存储桶
tblproperties(“ transactional” =“ true”,“ skip.header.line.count” =“ 1”);
将数据从外部表插入内部表
插入表table1 从您的外部表中选择*;
运行您的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) ;
覆盖基本文件导出内部表
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;
希望这将有助于解决您的问题
谢谢
尼罗什