如何在Pig中强制STORE(覆盖)到HDFS?

val*_*lid 17 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://[server]/user/[user]/foo/bar already exists
Run Code Online (Sandbox Code Playgroud)

所以我正在寻找一个in-Pig解决方案来自动删除目录,如果目录在呼叫时不存在,那么该目录也不会阻塞.

在Pig Latin Reference中我找到了shell命令调用者fs.不幸的是,只要出现任何错误,Pig脚本就会中断.所以我不能用

fs -rmr foo/bar
Run Code Online (Sandbox Code Playgroud)

(即递归删除)因为如果目录不存在它会中断.我想我可以用一会儿

fs -test -e foo/bar
Run Code Online (Sandbox Code Playgroud)

这是一个测试,不应该打破或所以我想.但是,Pig再次将test不存在的目录上的返回代码解释为失败代码并中断.

Pig项目有一个JIRA票据解决了我的问题,并为STORE命令建议了一个可选参数OVERWRITEFORCE_WRITE.无论如何,我正在使用Pig 0.8.1,并且没有这样的参数.

val*_*lid 42

最后我找到了一个关于grokbase的解决方案.由于找到解决方案花了太长时间,我会在这里重现它并添加它.

假设您要使用语句存储输出

STORE Relation INTO 'foo/bar';
Run Code Online (Sandbox Code Playgroud)

然后,为了删除目录,您可以在脚本的开头调用

rmf foo/bar
Run Code Online (Sandbox Code Playgroud)

不";" 或者是必需的引用,因为它是一个shell命令.

我现在无法重现它,但在某个时间点我得到了一条错误消息(关于丢失文件的东西),我只能假设rmf干扰了map/reduce.所以我建议在任何关系声明之前发出呼叫.在SET之后,REGISTERs和默认值应该没问题.

例:

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';
Run Code Online (Sandbox Code Playgroud)

  • @MiguelPing:在我看来,你的方法应该遇到我最初的问题但是对于`foobar-tmp`而不是`foo/bar`.首先存储也可能产生难以捉摸的错误,我暂时将其归因于map/reduce.如果您的解决方案适合您,您可以使用示例脚本将其转换为答案并提供您的猪版本号吗? (2认同)