Apache pig 如何在Pig中强制存储(覆盖)HDFS?

Apache pig 如何在Pig中强制存储(覆盖)HDFS?,apache-pig,hdfs,Apache Pig,Hdfs,在开发使用STORE命令的Pig脚本时,我必须删除每次运行的输出目录,或者脚本停止并提供: 2012-06-19 19:22:49,680 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 6000: Output Location Validation Failed for: 'hdfs://[server]/user/[user]/foo/bar More info to follow: Output directory hdfs:/

在开发使用STORE命令的Pig脚本时,我必须删除每次运行的输出目录,或者脚本停止并提供:

2012-06-19 19:22:49,680 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 6000: Output Location Validation Failed for: 'hdfs://[server]/user/[user]/foo/bar More info to follow:
Output directory hdfs://[server]/user/[user]/foo/bar already exists
因此,我正在搜索一个in-Pig解决方案来自动删除目录,如果在调用时目录不存在,这个解决方案也不会阻塞

在Pig拉丁文参考中,我找到了shell命令调用程序fs。不幸的是,每当出现错误时,Pig脚本就会中断。所以我不能用

fs -rmr foo/bar
(即递归删除)因为如果目录不存在它就会中断。有那么一会儿我想我可以用

fs -test -e foo/bar
这是一个测试,不应该打破,至少我是这么想的。但是,Pig再次将不存在的目录上的
test
返回代码解释为故障代码并中断


Pig项目有一个解决我的问题的方法,建议为STORE命令使用可选参数OVERRIDE或FORCE_WRITE。无论如何,出于必要,我使用Pig 0.8.1,但没有这样的参数。

最后我在上找到了一个解决方案。因为找到解决方案花了太长时间,我将在这里复制它并添加到它

假设要使用语句存储输出

STORE Relation INTO 'foo/bar';
然后,为了删除目录,您可以在脚本开始时调用

rmf foo/bar
不需要“;”或引号,因为它是一个shell命令

我现在无法复制它,但在某个时间点,我收到了一条错误消息(关于丢失文件的信息),我只能假设rmf干扰了map/reduce。因此,我建议将调用放在任何关系声明之前。设置之后,寄存器和默认值应该可以

例如:

SET mapred.fairscheduler.pool 'inhouse';
REGISTER /usr/lib/pig/contrib/piggybank/java/piggybank.jar;
%default name 'foobar'
rmf foo/bar
Rel = LOAD 'something.tsv';
STORE Rel INTO 'foo/bar';

使用fs命令后,有很多方法可以做到这一点。对于单个文件,我在脚本的开头添加了以下内容:

-- Delete file (won't work for output, which will be a directory
-- but will work for a file that gets copied or moved during the
-- the script.)
fs -touchz top_100
rm top_100
查找目录

-- Delete dir
fs -rm -r out

虽然这确实很好,但它不是原子的。我宁愿分三步来做:1)存储在“foobar tmp”中2)rmf foo/bar 3)mv“foobar tmp”到foo/bar@MiguelPing:在我看来,您的方法应该会遇到我最初的问题,但是对于
foobar tmp
而不是
foo/bar
。先存储也可能产生我暂时认为是map/reduce造成的难以捉摸的错误。如果您的解决方案对您有效,您能用示例脚本将其转换为答案并提供您的pig版本号吗?@valid我的解决方案与您的类似,我只是添加了一个额外的步骤,以确保如果
rmf
存储之间发生了什么事情(比如,异常),您不会丢失数据。Pig脚本随时可能失败,因此我的解决方案也不是原子的,但至少您不会有丢失数据的风险。非常感谢您!我试图寻找一个类似的函数,但不知怎么的,我在官方文档中找不到它。