0

意味をなさない Hadoop フレームワークの製品コードを見ています。なぜ一時的なものを使用しているのか、またユーティリティ メソッドを静的メソッドにできないのはなぜですか (主任から isThinger を静的メソッドにしないように言われました)。一時的なキーワードを調べたところ、シリアライゼーションに関連しています。シリアル化は本当にここで使用されていますか?

//extending from MapReduceBase is a requirement of hadoop
public static class MyMapper extends MapReduceBase {

    // why the use of transient keyword here?
    transient Utility utility;

    public void configure(JobConf job) {

        String test = job.get("key");

        // seems silly that we have to create Utility instance.
        // can't we use a static method instead?
        utility = new Utility();

        boolean res = utility.isThinger(test);

        foo (res);
    }

    void foo (boolean a) { }
}


public class Utility {
   final String stringToSearchFor = "ineverchange";

   // it seems we could make this static.  Why can't we?
   public boolean isThinger(String word) {
      boolean val = false;
      if (word.indexOf(stringToSearchFor) > 0) {
           val = true;
      }
      return val;
   }
}
4

2 に答える 2

2

コードの問題は、ローカル モード (dev&testcases が通常使用するモード) と分散モードの違いです。

ローカル モードでは、すべてが単一の JVM 内にあるため、静的変数 (または、この場合は何らかの状態を共有する静的メソッドstringToSearchFor) を変更すると、その変更はすべてのチャンクの計算で表示されると安全に想定できます。入力。

分散モードでは、すべてのチャンクが独自の JVM で処理されます。したがって、状態を変更すると (eG in stringToSearchFor)、他のホスト/jvm/タスクで実行される他のすべてのプロセスでは表示されなくなります。

これは、map/reduce 関数を記述する際に次の設計原則につながる矛盾です。

  1. 可能な限りステートレスにします。
  2. 状態 (可変クラスなど) が必要な場合は、map/reduce クラスで参照を宣言しないstaticでください(そうしないと、テスト/開発時と本番環境での動作が異なります)
  3. 不変の定数 (たとえば、構成キー as String) を定義staticし、final.

transientHadoop ではほとんど役に立ちません。Hadoop はユーザーコード (Mapper/Reducer) クラス/オブジェクトで何もシリアライズしていません。私たちが知らないJavaシリアライゼーションで何かをした場合にのみ、これが問題になります

あなたの場合Utilityが本当にユーティリティでstringToSearchForあり、不変の定数である場合(したがって、変更されることはありません)、isThingerとして安全に宣言できますstatictransientで Java シリアライゼーションを行わない場合は、それを削除してくださいMapReduceBase

于 2013-02-07T08:16:55.787 に答える
0

Unless there is something not shown here, then I suspect that the matter of making Utility a static method largely comes down to style. In particular, if you are not injecting the Utility instance rather than instantiating it on demand within, then it is rather pointless. As it is written, it cannot be overridden nor can it be more easily tested than static method.

As for transient, you are right that it is unnecessary. I wouldn't be surprised if the original developer was using Serialization somewhere in the inheritance or implementation chain, and that they were avoiding a compiler warning by marking the non-serializable instance variable as transient.

于 2013-02-07T04:39:11.760 に答える