设置 ORC 文件名
Set ORC file name
我目前正在将监控数据的 ETL (Talend) 实施到 HDFS 和 Hive table。
我现在面临着对重复的担忧。更详细地说,如果我们需要使用相同的输入 运行 一个 ETL 作业 2 次,我们将在 Hive table.
中得到重复项
RDMS 中的解决方案是在发送数据之前存储输入文件名和 "DELETE WHERE file name=..."。但是Hive不是RDBMS,不支持删除
我想就如何处理这个问题征求您的意见。我设想了两种解决方案:
- 实际上,ETL 正在将 CSV 文件放入 HDFS,用于向 ORC table 提供 "INSERT INTO TABLE ... SELECT ..." 问题是,通过此操作,我失去了文件名,ORC 文件名为 00000。是否可以指定此创建的 ORC 文件的文件名?如果是,我将能够通过文件名搜索数据并在启动 ETL 之前将其删除。
- 我不习惯 Hive 的 ACID 功能(Hive 0.14+ 上的功能)。 您会推荐使用 Hive 启用 ACID 吗?我可以使用它 "DELETE WHERE" 吗?
如果您有任何其他解决方案,请随时提出建议。
最佳,
奥兰多
如果目标table中的数据量不会太大,我会建议
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,将目标 table 中的所有候选键提取到 Java HashMap 中,并实时过滤源行。只要 HashMap 可以适应 Mappers 堆大小 可用的 RAM(检查您的默认配置文件,必要时在 Hive 脚本中使用 set
命令增加) 性能将是次优的,但你可以很确定你不会有任何重复。
而在您的实际用例中您不必检查每个键,而只需检查一个"batch ID",更多正是原始文件名;我在上一份工作中的做法是
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>>
)
这意味着您的目标中有一个额外的列 table,但由于 ORC 是一种列格式,因此重要的是不同值的数量——这样开销就会保持在较低水平。
注意子查询中显式的"DISTINCT";一个成熟的 DBMS 优化器会在执行时自动执行它,但 Hive 不会(还没有)所以你必须强制它。另请注意,由于 "SELECT" 语义,“1”只是一个虚拟值;同样,成熟的 DBMS 将允许虚拟 "null" 但某些版本的 Hive 会崩溃(例如,在 V0.14 中使用 Tez),因此“1”或“'A'”更安全。
参考:
我在回答我自己。我找到了一个解决方案:
我用 (date,input_file_name) 对 table 进行了分区(注意,我可以用 SELECT [=20= 得到 input_file_name ] 在蜂巢中。
完成此操作后,在 运行 ETL 之前,我可以向 Hive 发送一个 ALTER TABLE DROP IF EXISTS PARTITION (file_name=...) 以便包含输入数据的文件夹是如果此 INPUT_FILE 已发送至 ORC table.
,则删除
谢谢大家的帮助。
干杯,
奥兰多
我目前正在将监控数据的 ETL (Talend) 实施到 HDFS 和 Hive table。 我现在面临着对重复的担忧。更详细地说,如果我们需要使用相同的输入 运行 一个 ETL 作业 2 次,我们将在 Hive table.
中得到重复项RDMS 中的解决方案是在发送数据之前存储输入文件名和 "DELETE WHERE file name=..."。但是Hive不是RDBMS,不支持删除
我想就如何处理这个问题征求您的意见。我设想了两种解决方案:
- 实际上,ETL 正在将 CSV 文件放入 HDFS,用于向 ORC table 提供 "INSERT INTO TABLE ... SELECT ..." 问题是,通过此操作,我失去了文件名,ORC 文件名为 00000。是否可以指定此创建的 ORC 文件的文件名?如果是,我将能够通过文件名搜索数据并在启动 ETL 之前将其删除。
- 我不习惯 Hive 的 ACID 功能(Hive 0.14+ 上的功能)。 您会推荐使用 Hive 启用 ACID 吗?我可以使用它 "DELETE WHERE" 吗?
如果您有任何其他解决方案,请随时提出建议。
最佳, 奥兰多
如果目标table中的数据量不会太大,我会建议
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,将目标 table 中的所有候选键提取到 Java HashMap 中,并实时过滤源行。只要 HashMap 可以适应 Mappers 堆大小 可用的 RAM(检查您的默认配置文件,必要时在 Hive 脚本中使用 set
命令增加) 性能将是次优的,但你可以很确定你不会有任何重复。
而在您的实际用例中您不必检查每个键,而只需检查一个"batch ID",更多正是原始文件名;我在上一份工作中的做法是
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>>
)
这意味着您的目标中有一个额外的列 table,但由于 ORC 是一种列格式,因此重要的是不同值的数量——这样开销就会保持在较低水平。
注意子查询中显式的"DISTINCT";一个成熟的 DBMS 优化器会在执行时自动执行它,但 Hive 不会(还没有)所以你必须强制它。另请注意,由于 "SELECT" 语义,“1”只是一个虚拟值;同样,成熟的 DBMS 将允许虚拟 "null" 但某些版本的 Hive 会崩溃(例如,在 V0.14 中使用 Tez),因此“1”或“'A'”更安全。
参考:
我在回答我自己。我找到了一个解决方案: 我用 (date,input_file_name) 对 table 进行了分区(注意,我可以用 SELECT [=20= 得到 input_file_name ] 在蜂巢中。 完成此操作后,在 运行 ETL 之前,我可以向 Hive 发送一个 ALTER TABLE DROP IF EXISTS PARTITION (file_name=...) 以便包含输入数据的文件夹是如果此 INPUT_FILE 已发送至 ORC table.
,则删除谢谢大家的帮助。
干杯, 奥兰多