我有十几个Web服务器,每个都将数据写入日志文件。在每小时开始时,使用运行命令的cron脚本将前一小时的数据加载到配置单元:
hive -e "LOAD DATA LOCAL INPATH 'myfile.log' INTO TABLE my_table PARTITION(dt='2015-08-17-05')"
在某些情况下,命令失败并以0以外的代码退出,在这种情况下,我们的脚本等待并再次尝试。问题是,在某些情况下失败,数据加载不失败,即使它显示失败消息。我如何确定数据是否已加载?
加载数据
>的“失败”示例:将数据加载到表default.my_table分区(dt = 2015-08-17-05) 异常失败 org.apache.hadoop.hive.ql.metadata.HiveException:无法更改 划分。 FAILED:执行错误,返回代码1 org.apache.hadoop.hive.ql.exec.MoveTask
修改
或者,有没有办法查询hive加载到其中的文件名?我可以使用DESCRIBE
查看文件数量。我可以知道他们的名字吗?
答案 0 :(得分:2)
关于“已在分区中加载了哪些文件”:
EXTERNAL TABLE
并刚刚上传了原始数据
映射到LOCATION
的HDFS目录中的文件,然后你可以(a)从命令行在该目录上运行hdfs dfs -ls
(或使用等效的Java API调用)
(b)运行Hive查询,例如select distinct INPUT__FILE__NAME from (...)
sed
完成)关于“如何自动避免INSERT上的重复”:有一种方法,但它需要相当多的重新设计,并且在处理时间/(额外的Map步骤加MapJoin)/方面会花费你。 ..
EXTERNAL TABLE
,以便您可以运行
INSERT-SELECT查询INPUT__FILE__NAME
伪列作为源添加一个带有相关子查询的WHERE NOT EXISTS
子句,这样如果源文件名已经存在于目标中,那么就不再加载
INSERT INTO TABLE Target
SELECT ColA, ColB, ColC, INPUT__FILE__NAME AS SrcFileName
FROM Source src
WHERE NOT EXISTS
(SELECT DISTINCT 1
FROM Target trg
WHERE trg.SrcFileName =src.INPUT__FILE__NAME
)
注意实际需要的愚蠢的DISTINCT,以避免吹掉Mappers中的RAM;对于像Oracle这样成熟的DBMS来说它会毫无用处,但是Hive优化器仍然相当粗糙......
答案 1 :(得分:0)
我不相信你可以简单地在Hadoop / Hive中这样做。以下是python中实现的基础知识:
import subprocess
x=subprocess.check_output([hive -e "select count(*) from my_table where dt='2015-08-17-05'"])
print type(x)
print x
但你必须花一些时间使用反斜杠才能让hive -e使用python工作。这可能非常困难。首先使用该简单查询编写文件可能更容易,然后使用hive -f filename
。然后,打印subprocess.check_output
的输出以查看输出的存储方式。您可能需要执行一些正则表达式或类型转换,但我认为它应该以字符串形式返回。然后只需使用if语句:
if x > 0:
pass
else:
hive -e "LOAD DATA LOCAL INPATH 'myfile.log' INTO TABLE my_table PARTITION(dt='2015-08-17-05')"