设置ORC文件名

时间:2016-02-16 08:27:47

标签: hadoop hive etl

我目前正在实施监控数据到HDFS和Hive表的ETL(Talend)。 我现在面临重复的问题。更详细的说,如果我们需要使用相同的输入运行一次ETL作业2次,我们最终会在Hive表中找到重复项。

RDMS中的解决方案是将输入文件名存储到" DELETE WHERE文件名= ..."在发送数据之前。但是Hive不是RDBMS,并且不支持删除。

我想就如何处理这个问题提出建议。我设想了两个解决方案:

  • 实际上,ETL正在将CSV文件放入HDFS,用于向ORC表提供" INSERT INTO TABLE ... SELECT ..."问题是,通过此操作,我丢失了文件名,ORC文件名为00000. 是否可以指定此创建的ORC文件的文件名?如果是,我可以通过它的文件名搜索数据,并在启动ETL之前将其删除。
  • 我不习惯Hive的ACID功能(Hive 0.14+上的功能)。 您是否建议使用Hive启用ACID?我是否可以" DELETE WHERE"用它?

如果您有任何其他解决方案,请随意提出建议。

贝斯茨, 奥兰多

2 个答案:

答案 0 :(得分:0)

如果目标表中的数据量不太大,我建议

INSERT INTO TABLE trg
SELECT ... FROM src
WHERE NOT EXISTS
 (SELECT 1
  FROM trg x
  WHERE x.key =src.key
    AND <<additional filter on target to reduce data volume>> 
 )

Hive会自动将相关的子查询重写为MapJoin,将目标表中的所有候选键提取到Java HashMap中,并即时过滤源行。只要HashMap可以适合可用于Mappers堆大小的RAM(检查你的默认conf文件,如果需要,在Hive脚本中使用set命令增加),性能将是最佳,但你可以肯定你不会有任何重复。

在您的实际使用案例中,您不必检查每个密钥,而只需检查&#34;批次ID&#34;,更准确地说是原始文件名;我在以前的工作中完成它的方式是

INSERT INTO TABLE trg
SELECT ..., INPUT__FILE__NAME as original_file_name
FROM src
WHERE NOT EXISTS
 (SELECT DISTINCT 1
  FROM trg x
  WHERE x.INPUT__FILE__NAME =src.original_file_name
    AND <<additional filter on target to reduce data volume>> 
 )

这意味着目标表中有一个额外的列,但由于ORC是一种列式格式,因此它是重要的不同值的数量 - 因此开销会保持较低。

请注意明确的&#34; DISTINCT&#34;在子查询中;一个成熟的DBMS优化器会在执行时自动执行它,但Hive不会(还没有)所以你必须强制它。另请注意&#34; 1&#34;只是因为&#34; SELECT&#34;所需的虚拟值。语义;再一次,一个成熟的DBMS将允许一个虚拟&#34; null&#34;但某些版本的Hive会崩溃(例如在V0.14中使用Tez)所以&#34; 1&#34;或&#34;&#39; A&#39;&#34;更安全。

参考:

答案 1 :(得分:0)

我正在回答自己。我找到了解决方案: 我用(date, input_file_name )对我的表进行了分区(注意,我可以在Hive中使用SELECT INPUT__FILE__NAME获取input_file_name。 一旦我这样做,在运行ETL之前,我可以向Hive发送一个ALTER TABLE DROP IF EXISTS PARTITION(file_name = ...),这样如果已经将此INPUT_FILE发送到ORC表,则删除包含输入数据的文件夹

谢谢大家的帮助。

干杯, 奥兰多