2017-03-28 1 views
0

スパーククロージャに関する基本的な質問があります。私はシナリオ2 & 3の間でコードの振る舞いを区別することができません、両方とも同じ出力を生成しますが、私の理解に基づいてシナリオ3は期待どおりに動作しません。スパーククロージャの動作

以下のコードは、すべてのシナリオに共通である:

class A implements Serializable{ 
     String t; 
     A(String t){ 
      this.t=t; 
     } 
    } 

//Initiaze spark context 
JavaSparkContext context=.... 
//create rdd 
JavaRDD<String> rdd = context.parallelize(Arrays.asList("a","b","c","d","e"),3); 

のscenerio 1:Aは、ドライバに初期化実行部に表示されていないためこれを行いません。

A a=new A("pqr"); 
rdd.map(i->i+a.t).collect(); 

のscenerio 2:共有オブジェクト

Broadcast<A> broadCast = context.broadcast(new A("pqr")); 
rdd.map(i->broadCast.getValue().t+i).collect(); 
//output: [pqra, pqrb, pqrc, pqrd, pqre] 

のscenerio 3の推奨方法:なぜ私は運転手にAを開始したときにも、期待通り、このコードは動作しますか?

class TestFunction implements Function<String, String>, Serializable { 
    private A val; 
    public TestFunction(){ } 
    public TestFunction(A a){ 
     this.val = a; 
    } 
    @Override 
    public String call(String integer) throws Exception { 
     return val.t+integer; 
    } 
} 
    TestFunction mapFunction = new TestFunction(new A("pqr")); 
    System.out.println(rdd.map(mapFunction).collect()); 
    //output: [pqra, pqrb, pqrc, pqrd, pqre] 

注:私はプログラムをクラスタモードで実行しています。

答えて

1

Scenerio 1 & 3のJavaバイトコードはほぼ同じです。ブロードキャスト(Scenerio 2)を使用する利点は、ブロードキャストオブジェクトが一度エグゼキュータに送信され、このエグゼキュータの他のタスクで再利用されることです。 Scenerio 1 & 3は、オブジェクトAを常に各タスクのエグゼキュータに送ります。

+0

ありがとうございました。 –