2010-03-29 20 views
6

Tôi có một hàm do người dùng định nghĩa (UDF) được viết bằng Java để phân tích cú pháp các dòng trong tệp nhật ký và trả về thông tin về lợn, vì vậy nó có thể thực hiện tất cả quá trình xử lý.Việc ném một ngoại lệ trong một UDF của EvalFunc có bỏ qua dòng đó hay dừng hoàn toàn không?

Nó trông giống như sau:

public abstract class Foo extends EvalFunc<Tuple> { 
    public Foo() { 
     super(); 
    } 

    public Tuple exec(Tuple input) throws IOException { 
     try { 
      // do stuff with input 
     } catch (Exception e) { 
      throw WrappedIOException.wrap("Error with line", e); 
     } 
    } 
} 

Câu hỏi của tôi là: nếu nó ném IOException, nó sẽ ngừng hoàn toàn, hoặc nó sẽ trả về kết quả cho phần còn lại của các dòng mà không ném một ngoại lệ ?

Ví dụ: Tôi chạy này ở lợn

REGISTER myjar.jar 
DEFINE Extractor com.namespace.Extractor(); 

logs = LOAD '$IN' USING TextLoader AS (line: chararray); 
events = FOREACH logs GENERATE FLATTEN(Extractor(line)); 

Với đầu vào này:

1.5 7 "Valid Line" 
1.3 gghyhtt Inv"alid line"" I throw an exceptioN!! 
1.8 10 "Valid Line 2" 

Nó sẽ xử lý hai dòng và 'log' sẽ có 2 bộ dữ liệu, hoặc sẽ nó chỉ chết trong Một đám cháy?

Trả lời

8

Nếu ngoại lệ được ném bởi UDF, nhiệm vụ sẽ thất bại và sẽ được thử lại.

Nó sẽ thất bại lần nữa ba lần nữa (4 lần thử theo mặc định) và toàn bộ công việc sẽ KHÔNG ĐƯỢC FAILED.

Nếu bạn muốn đăng nhập lỗi và không muốn có việc ngừng bạn có thể trả về một null:

public Tuple exec(Tuple input) throws IOException { 
    try { 
     // do stuff with input 
    } catch (Exception e) { 
     System.err.println("Error with ..."); 
     return null; 
    } 
} 

Và lọc chúng sau này trong Pig:

events_all = FOREACH logs GENERATE Extractor(line) AS line; 
events_valid = FILTER events_all by line IS NOT null; 
events = FOREACH events_valid GENERATE FLATTEN(line); 

Trong ví dụ của bạn đầu ra sẽ chỉ có hai dòng hợp lệ (nhưng hãy cẩn thận với hành vi này vì lỗi chỉ xuất hiện trong nhật ký và sẽ không thành công trong công việc của bạn!).

Trả lời nhận xét # 1:

Trên thực tế, toàn bộ tuple kết quả sẽ là null (vì vậy không có lĩnh vực bên trong).

Ví dụ, nếu giản đồ của bạn có 3 lĩnh vực:

events_all = FOREACH logs 
       GENERATE Extractor(line) AS line:tuple(a:int,b:int,c:int); 

và một số dòng là không chính xác, chúng tôi sẽ nhận được:

() 
((1,2,3)) 
((1,2,3)) 
() 
((1,2,3)) 

Và nếu bạn không lọc các dòng vô cố gắng truy cập một lĩnh vực mà bạn có được một java.lang.NullPointerException :

events = FOREACH events_all GENERATE line.a; 
+0

Trong trường hợp của tôi , Tôi cũng định nghĩa một lược đồ trong UDF, vì vậy bằng cách trả về null, mọi thứ trong tuple kết quả sẽ là null, đúng không? –

+0

Làm cách nào để lọc? LỰA CHỌN LỌC CỦA một IS NOT NULL, giả sử EvalFunc luôn trả về null nếu nó không thể tìm ra 'a'? –

+0

Bạn cần phải lọc tên của trường được trả về bởi UDF. Trong trường hợp của chúng tôi tên của nó là 'dòng' và giá trị của nó có thể là 'null' hoặc '(1,2,3)'. Vì vậy, bạn thực hiện 'FILTER events by line IS NOT null' như trong ví dụ Pig đầu tiên. Nếu bạn trả lại một bộ tuple có 3 trường rỗng, ví dụ: '(,,)' thay vì 'null', bạn có thể làm 'FILTER events BY line.a IS NOT NULL' nhưng nó ít đơn giản hơn. – Romain

Các vấn đề liên quan