hadoop中的瞬态变量和静态方法,dev寻求启示

时间:2013-02-07 04:25:20

标签: java multithreading hadoop

我正在研究hadoop框架中的生产代码,这是没有意义的。为什么我们使用瞬态,为什么我不能将实用程序方法变成静态方法(导致告知不要将isThinger作为静态方法)?我查找了transient关键字,它与序列化有关。这里是否真的使用了序列化?

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

2 个答案:

答案 0 :(得分:2)

代码中的问题是本地模式(通常使用它的dev& testcases)和分布式模式之间的区别。

在本地模式下,所有内容都将位于单个JVM中,因此您可以安全地假设,如果您更改静态变量(或者在您的情况下stringToSearchFor共享某个状态的静态方法),则更改将是对于每个输入块的计算都是可见的。

在分布式模式下,每个块都在自己的JVM中处理。因此,如果您更改状态(例如stringToSearchFor中),则对于在其他主机/ jvms / tasks上运行的每个其他进程都不会显示此状态。

这是一种不一致,在编写map / reduce函数时会产生以下设计原则:

  1. 尽可能无国籍。
  2. 如果您需要状态(例如,可变类),永远不会在map / reduce类static中声明引用(否则在测试/开发时将比在生产中表现不同)< / LI>
  3. 应该定义不可变常量(例如配置键为Stringstaticfinal
  4. Hadoop中的

    transient几乎没用,Hadoop没有在usercode(Mapper / Reducer)类/对象中序列化任何内容。只有当对我们不知道的Java序列化做一些事情时,这才是一个问题。

    对于您的情况,如果Utility实际上是一个实用程序而且stringToSearchFor是一个不可变常量(因此不会被更改),您可以安全地声明{{1作为isThinger。如果您不使用static进行任何Java序列化,请删除transient

答案 1 :(得分:0)

除非此处未显示任何内容,否则我怀疑制作Utility static方法的问题主要归结为风格。特别是,如果你没有注入Utility实例而不是在内部按需实例化它,那么它就毫无意义。在编写时,它不能被覆盖,也不能比static方法更容易测试。

至于transient,你是对的,没有必要。如果原始开发人员在继承或实现链中的某处使用Serialization,并且他们通过将不可序列化的实例变量标记为transient来避免编译器警告,我不会感到惊讶。