2012-06-19 23 views
14

Khi xây dựng các kịch bản Pig mà sử dụng CỬA HÀNG lệnh tôi phải xóa thư mục đầu ra cho mỗi chạy hoặc kịch bản dừng lại và cung cấp:Làm thế nào để buộc STORE (ghi đè) lên HDFS trong 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 

Vì vậy, tôi tìm kiếm một giải pháp in-Pig để tự động loại bỏ các thư mục, cũng là một trong đó không bị nghẹt thở nếu thư mục không tồn tại vào thời gian gọi.

Trong tham chiếu Pig Latin tôi tìm thấy lệnh shell invoker fs. Thật không may, kịch bản Pig phá vỡ bất cứ khi nào bất cứ điều gì tạo ra lỗi. Vì vậy, tôi không thể sử dụng

fs -rmr foo/bar 

(ví dụ: xóa đệ quy) vì nó bị hỏng nếu thư mục không tồn tại. Trong một khoảnh khắc, tôi nghĩ rằng tôi có thể sử dụng

fs -test -e foo/bar 

là một thử nghiệm và không nên phá vỡ hoặc vì vậy tôi nghĩ. Tuy nhiên, Pig lại giải thích mã trả về của test trên một thư mục không tồn tại dưới dạng mã lỗi và ngắt.

Có một JIRA ticket cho dự án Pig giải quyết vấn đề của tôi và đề xuất một tùy chọn tham số OVERWRITE hoặc FORCE_WRITE cho CỬA HÀNG lệnh. Dù sao, tôi đang sử dụng Pig 0.8.1 ra khỏi sự cần thiết và không có tham số như vậy.

Trả lời

40

Cuối cùng tôi tìm thấy giải pháp trên grokbase. Vì việc tìm kiếm giải pháp mất quá nhiều thời gian, tôi sẽ tái tạo nó ở đây và thêm vào đó.

Giả sử bạn muốn lưu trữ đầu ra của bạn sử dụng câu lệnh

STORE Relation INTO 'foo/bar'; 

Sau đó, để xóa các thư mục, bạn có thể gọi vào lúc bắt đầu của kịch bản

rmf foo/bar 

Không ";" hoặc yêu cầu trích dẫn vì nó là lệnh shell.

Tôi không thể tạo lại ngay bây giờ nhưng tại một thời điểm nào đó tôi nhận được thông báo lỗi (điều gì đó về các tệp bị thiếu) nơi tôi chỉ có thể giả định rằng rmf can thiệp vào bản đồ/giảm. Vì vậy, tôi khuyên bạn nên đặt cuộc gọi trước bất kỳ tuyên bố quan hệ nào. Sau khi SET, REGISTER và mặc định sẽ ổn.

Ví dụ:

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

Mặc dù đây là thực sự tốt đẹp, nó không phải là nguyên tử.Tôi muốn làm điều đó trong ba bước: 1) lưu trữ trong 'foobar-tmp' 2) rmf foo/bar 3) mv 'foobar-tmp' để foo/bar –

+2

@MiguelPing: Có vẻ như với tôi như cách tiếp cận của bạn nên chạy vào vấn đề ban đầu của tôi nhưng đối với 'foobar-tmp' thay vì' foo/bar'. Lưu trữ đầu tiên cũng có thể tạo ra lỗi khó nắm bắt mà tôi tạm thời quy cho bản đồ/giảm. Nếu giải pháp của bạn hoạt động trên mặt của bạn, bạn có thể biến nó thành câu trả lời bằng một tập lệnh mẫu và cung cấp số phiên bản lợn của bạn không? – valid

+0

@valid giải pháp của tôi là tương tự như của bạn, tôi chỉ cần thêm một bước bổ sung để đảm bảo rằng nếu một cái gì đó xảy ra giữa 'rmf' và' STORE' (nói, ngoại lệ) bạn không bị mất dữ liệu. Script Pig có thể thất bại bất cứ lúc nào, vì vậy giải pháp của tôi không phải là nguyên tử, nhưng ít nhất bạn không có nguy cơ mất dữ liệu. –

2

Khi bạn sử dụng lệnh fs, có rất nhiều cách để làm điều này. Đối với một tập tin cá nhân, tôi lên vết thương thêm này đến đầu kịch bản của tôi:

-- 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 

Đối với một thư mục

-- Delete dir 
fs -rm -r out 
Các vấn đề liên quan