我想知道是否可以添加一个可以在多个map()调用中使用的成员对象。例如,StringBuilder:
private StringBuilder builder;
public void map(...){
...
builder.setLength(0);
builder.append(a);
builder.append(b);
builder.append(c);
d = builder.toString();
...
}
显然,如果映射器对象跨多个线程共享,则由于多个线程的并发访问,上面的构建器对象将不会按预期运行。
所以我的问题是:是否确保hadoop中的每个线程都会使用一个专用的mapper对象?或者它是一种可配置的行为?
由于
答案 0 :(得分:2)
只要您不使用MultithreadedMapper
课程,而不是您自己的课程,就没有问题。 map()
被称为顺序而非并行。
通常使用StringBuilder
或其他数据结构来缓冲调用之间的一些对象。
但是请确保从输入对象克隆对象,只有一个对象,它将反复填充以防止大量GC。
因此无需同步或处理竞争条件。
答案 1 :(得分:0)
我认为这不可行。原因是每个映射器都在自己的JVM中运行(它们将分布在不同的机器上),因此您无法轻松地在多个映射器或缩减器之间共享变量或对象。
现在如果你的所有映射器都运行在同一个节点上,我相信在某个地方有一个JVM重用配置,但老实说我不打扰它,特别是如果你需要的只是StringBuilder
:)< / p>
我曾经见过这个问题,通过改变应用程序的设计可以很容易地解决它。也许你可以通过这个来了解更多关于你想要实现的目标,看看是否真的需要这样做。如果你真的需要它,你仍然可以序列化你的对象,把它放在HDFS中,然后用每个映射器读取它,反序列化它,但这似乎是倒退。