2012-06-19 60 views
14

當開發使用STORE命令豬劇本我已經刪除了輸出目錄每次運行或腳本停止,並提供:如何在Pig中強制存儲(覆蓋)到HDFS?

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 

所以我尋找一種在豬的解決方案自動刪除目錄,如果目錄在通話時不存在,也不會窒息。

在豬拉丁文參考中,我找到了shell命令調用程序fs。不幸的是,只要有任何錯誤產生,Pig腳本就會中斷所以我不能使用

fs -rmr foo/bar 

(即遞歸地刪除),因爲如果該目錄不存在就會中斷。有一刻我想我可以用

fs -test -e foo/bar 

這是一個測試,不應該打破或所以我認爲。但是,Pig再次將test的返回碼解釋爲不存在的目錄,並將其作爲失敗代碼並中斷。

沒有爲豬項目解決我的問題,並提出了STORE命令的可選參數OVERWRITEFORCE_WRITE一個JIRA ticket。無論如何,我正在使用Pig 0.8.1,並且沒有這個參數。

回答

40

最後我在grokbase上找到了解決方案。由於找到解決方案需要很長時間,我將在這裏重新制作並添加到其中。

假設你想使用的語句

STORE Relation INTO 'foo/bar'; 

然後,爲了刪除目錄來存儲你的輸出,你可以在腳本

rmf foo/bar 

沒有開始打電話「;」或者因爲它是一個shell命令所需的引用。

我現在不能重現它,但是在某個時間點,我收到了一條錯誤消息(關於丟失文件的地方),我只能假設rmf干擾了map/reduce。所以我建議在任何關係聲明前打電話。 SETs後,註冊和默認值應該沒問題。

例子:

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'; 
+0

雖然這確實是不錯的,它不是原子。我寧願這樣做的三個步驟:1)存儲在'foobar-tmp'2)rmf foo/bar 3)mv'foobar-tmp'到foo/bar –

+2

@MiguelPing:它在我看來像你的方法應該碰到我最初的問題,但爲'foobar-tmp'而不是'foo/bar'。首先存儲也可能產生我暫時歸因於map/reduce的難以捉摸的錯誤。如果您的解決方案能夠在您身邊工作,您可以用示例腳本將它變成答案並提供您的豬版本號? – valid

+0

@我的解決方案無效與您的解決方案類似,我只是增加了一個額外的步驟,以確保如果rmf和STORE之間發生了某種情況(例如異常),則不會丟失數據。豬腳本可以隨時失敗,所以我的解決方案也不是原子的,但至少你不會冒丟失數據的風險。 –

2

一旦你使用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