5

我想知道是否可以添加一个可以在多个 map() 调用中使用的成员对象。例如,一个 StringBuilder:

private StringBuilder builder;

public void map(...){
    ...

    builder.setLength(0);
    builder.append(a);
    builder.append(b);
    builder.append(c);
    d = builder.toString();

    ...
}

显然,如果 mapper 对象在多个线程之间共享,由于来自多个线程的并发访问,上面的 builder 对象将不会像预期的那样运行。

所以我的问题是:是否保证 hadoop 中的每个线程都会为自己使用一个专用的映射器对象?或者它是一种可配置的行为?

谢谢

4

2 回答 2

2

只要你使用的不是MultithreadedMapper类,而是你自己的,就没有问题。map()称为顺序而不是并行。

通常使用 aStringBuilder或其他数据结构在调用之间缓冲一些对象。但是请确保从输入对象中克隆对象,只有一个对象,并且会一遍又一遍地填充以防止大量 GC。

因此无需同步或处理竞争条件。

于 2012-04-16T05:46:27.967 回答
0

我不认为这是可能的。原因是每个映射器都在自己的 JVM 中运行(它们将分布在不同的机器上),因此您无法轻松地在多个映射器或化简器之间共享变量或对象。

现在,如果您所有的映射器都在同一个节点上运行,我相信在某处有一个 JVM 重用配置,但老实说,我不会为此烦恼,特别是如果您只需要一个StringBuilder:)

这个问题我以前见过一次,通过改变应用程序的设计可以很容易地解决这个问题。也许您可以更多地了解您正在尝试使用它来完成什么,以查看是否真的需要这样做。如果你真的需要它,你仍然可以序列化你的对象,把它放在 HDFS 中,然后用每个映射器读取它,反序列化它,但这似乎是倒退的。

于 2012-04-16T02:58:54.563 回答