2

我的 map reduce 作业类中有一个静态对象,我想初始化一次(在 main 方法中),然后在每个映射中调用它的函数。所以我有这个对象,我声明为变量的 MyObject:

static MyObject obj;

在我的主要功能中,在我开始工作之前,我调用:

obj = new MyObject();
obj.init();

然后在我的地图函数中我想调用:

obj.execute();

但是由于某种原因,当我尝试此操作时出现空指针异常(它说 obj 为空)。如果我在我的主函数中初始化它,映射器不应该将它视为已初始化吗?映射器是否看到静态变量?

4

3 回答 3

7

静态对象驻留在内存中。现在您的系统是分布式的,因此您创建的对象位于运行作业跟踪器的节点的内存中,而不是在其他系统上。

现在您不能将对象从作业传递到映射器,因为配置是写为 xml,但是有一种解决方法,将您的对象序列化为 JSON,然后将其作为字符串放入您的配置中,并在映射器中反序列化此 json 对象

为工作

job.getConfiguration().set("some key", "json string")

用于映射器

Configuration conf = context.getConfiguration();
conf.get("some key");
于 2012-10-17T14:38:55.287 回答
3

您的 main() 不会在每个节点上调用,它仅在您启动作业的地方运行。为了访问您的静态对象,需要在映射器的实例化时对其进行初始化。这样初始化将发生在每个运行地图任务的节点上。

但是可能还有另一种方法可以做你想要完成的事情,所以问题是,这个静态对象有什么作用?

于 2012-10-17T14:47:34.657 回答
0

由于我的对象实际上是在加载一个库,因此我最终使用了分布式缓存并仅在 M/R 方法中实例化该对象。

于 2012-10-18T18:16:46.947 回答