0

MapReduce ジョブで Avro を使用すると、静かで奇妙な動作が見られました。実際、使用されている Iterable は非常に奇妙です: iterator.next はオブジェクトを指すのではなく、関数「next」の呼び出しごとに値が変化するものを指します!!

例 :

public static class MyAvroReducer extends AvroReducer<Long, MyAvroType,
Pair<Long, MyAvroType>> {


    @Override
    public void reduce(Long user, Iterable<MyAvroType> listAvroType,
            AvroCollector<Pair<Long,MyAvroType>> collector,
            Reporter reporter)
    throws IOException {
        // basically here I am expecting a list of two MyAvroType object
        // The first one who has a field "type" equals to "foo" and the second
        // who has a filed "type" equals to "bar"

        MyAvroType foo;
        MyAvroType bar;

        for (MyAvroType obj : listAvroType){
           if (obj.getType().equals("foo") {foo = obj;}
           else if (obj.getType().equals("bar") {bar = obj;}

        }
        system.out.println("FOO: " + foo.getType());
        system.out.println("FOO: " + bar.getType());

}

標準出力には次のように表示されます。

フー:バー

BAR:バー

ここで Iterable はどのようにコーディングされていますか? なぜ ??それとも私は何か間違ったことをしていますか?

4

1 に答える 1

1

私は同じ問題を抱えていたので、あなたの質問を見つけました。私が実行したテストは、すべての反復で Iterable によって返されるインスタンスが 1 つだけであることを示しているようです。Iterable は、新しい AVRO オブジェクトを読み取るたびに、同じオブジェクトのコンテンツを置き換える必要があります。最後に返された何千ものオブジェクトのリストになりました。iterator.next() を呼び出すとすぐに、前の繰り返しから持っていたオブジェクトが突然新しいオブジェクトに変形することがわかりました。

Iterable は、処理を通じて無制限の数のオブジェクトを有効にするために使用されるため、つまり、一度にメモリに収まる可能性があるよりも多くのオブジェクトを有効にするために、なぜ彼らがこのようにするのか、私にはある程度理解できます。そのため、iterator.next() の呼び出し後に誰かがオブジェクトを保持することを期待していません。

iterable から返された以前のオブジェクトを参照する必要がある場合は、Iterable の次のオブジェクトに移動する前に、オブジェクトを新しいインスタンスにコピーする必要があります。

この問題を解決するために、Google の cloning-1.8.5 ツールの Cloner を使用しました。私のオブジェクトはネストの深さが約 5 ~ 6 レベルですが、機能しているように見えました。

Google クローニング-1.8.5

もう 1 つの方法は、すべてのオブジェクトに独自のコピー メソッドを実装することです。

ありがとう、ヴィック

于 2014-04-02T12:29:48.850 に答える