6

ログ ファイル内の行を解析し、情報を pig に返すために Java で記述されたユーザー定義関数 (UDF) があるため、すべての処理を行うことができます。

次のようになります。

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);
        }
    }
}

私の質問は、IOException をスローした場合、完全に停止するか、それとも例外をスローしない残りの行の結果を返すかということです。

例: これを pig で実行します

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

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

この入力で:

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

それは 2 行を処理し、「ログ」には 2 つのタプルがありますか、それとも単に火事で死ぬのでしょうか?

4

1 に答える 1

8

UDF によって例外がスローされた場合、タスクは失敗し、再試行されます。

さらに 3 回失敗し (デフォルトでは 4 回)、ジョブ全体が失敗します。

エラーをログに記録し、ジョブを停止させたくない場合は、null を返すことができます。

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

そして、後で 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);

あなたの例では、出力には2つの有効な行しかありません(ただし、エラーはログにのみ存在し、ジョブが失敗しないため、この動作には注意してください!)。

コメント #1 への返信:

実際には、結果のタプル全体が null になります (そのため、内部にフィールドはありません)。

たとえば、スキーマに 3 つのフィールドがある場合:

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

一部の行は正しくありません。次のようになります。

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

null 行をフィルタリングせずにフィールドにアクセスしようとすると、java.lang.NullPointerExceptionが発生します。

events = FOREACH events_all GENERATE line.a;
于 2010-03-29T23:04:28.483 に答える