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

6rvt4ljy  于 2021-06-04  发布在  Hadoop
关注(0)|答案(2)|浏览(375)

我正在看hadoop框架中的产品代码,这是没有意义的。为什么我们要使用transient,为什么我不能使实用方法成为静态方法(领导告诉我不要使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;
   }
}
vm0i2vca

vm0i2vca1#

除非这里没有显示什么,否则我怀疑 Utilitystatic 方法主要归结为风格。特别是,如果你没有注射 Utility 示例而不是按需在其中示例化,那么它就毫无意义了。正如它所写的那样,它不能被重写,也不能比以前更容易地被测试 static 方法。
至于 transient ,你是对的,这是不必要的。如果最初的开发人员在继承或实现链的某个地方使用序列化,并且他们通过将不可序列化的示例变量标记为 transient .

w8biq8rn

w8biq8rn2#

代码中的问题是本地模式(dev&testcases通常使用它)和分布式模式之间的差异。
在本地模式下,所有内容都将在一个jvm中,因此您可以安全地假设,如果您更改了一个静态变量(或者在您的情况下更改了一个共享某些状态的静态方法) stringToSearchFor )对于每个输入块的计算,这种变化都是可见的。
在分布式模式下,每个块都在自己的jvm中处理。所以如果你改变了状态(例如 stringToSearchFor )对于在其他主机/jvm/任务上运行的其他每个进程,这都是不可见的。
这种不一致性导致在编写map/reduce函数时遵循以下设计原则:
尽可能无国籍。
如果需要state(例如可变类),请不要在map/reduce类中声明引用 static (否则,测试/开发时的行为将与生产时不同)
不可变常量(例如配置键) String )应该定义 static 以及 final . transient 在hadoop中,hadoop没有序列化usercode(mapper/reducer)类/对象中的任何内容。只有当您对我们不知道的java序列化做了一些事情时,这才是一个问题。
对于你的情况,如果 Utility 是一种实用的 stringToSearchFor 是一个不可变的常量(因此永远不会更改),您可以安全地声明 isThinger 作为 static . 请把它拿走 transient ,如果不使用 MapReduceBase .

相关问题