我的程序遵循迭代map / reduce方法。如果满足某些条件,它需要停止。无论如何我可以设置一个可以分布在所有map / reduce任务中的全局变量,并检查全局变量是否达到完成条件。
像这样。
While(Condition != true){
Configuration conf = getConf();
Job job = new Job(conf, "Dijkstra Graph Search");
job.setJarByClass(GraphSearch.class);
job.setMapperClass(DijkstraMap.class);
job.setReducerClass(DijkstraReduce.class);
job.setOutputKeyClass(IntWritable.class);
job.setOutputValueClass(Text.class);
}
where condition是在每个map / reduce执行期间/之后修改的全局变量。
答案 0 :(得分:6)
每次运行map-reduce作业时,您都可以检查输出的状态,计数器中包含的值等,并在控制迭代的节点上决定是否再需要一次迭代或不。我想我不明白你的场景中对全球状态的需求来自何处。
更一般地说 - 在执行节点之间共享状态有两种主要方式(尽管应该注意共享状态最好避免,因为它限制了可伸缩性)。
答案 1 :(得分:6)
您可以使用 Configuration.set(字符串名称,字符串值)来设置您可以在Mappers / Reducers / etc中访问的值:
在你的司机中:
conf.set("my.dijkstra.parameter", "value");
例如在你的映射器中:
public void configure(JobConf job) {
myParam = job.get("my.dijkstra.parameter");
}
但这不太可能帮助您查看以前作业的输出以决定是否再开始一次迭代。即在执行作业后,该值不会被推回。
您还可以使用Hadoop的DistributedCache来存储将在所有节点之间分发的文件。如果您要通过这种方式传递的值很小,这比仅仅在HDFS上存储一些东西要好一些。
当然counters也可以用于此目的。但是,为了在算法中做出决策,它们看起来不太可靠。看起来在某些情况下,它们可以递增两次(如果某个任务执行了一次以上,例如在失败或投机执行的情况下) - 我不确定。
答案 2 :(得分:3)
这是它在Hadoop 2.0中的工作方式
在你的司机中:
conf.set("my.dijkstra.parameter", "value");
在Mapper中:
protected void setup(Context context) throws IOException,
InterruptedException {
Configuration conf = context.getConfiguration();
strProp = conf.get("my.dijkstra.parameter");
// and then you can use it
}
答案 3 :(得分:0)
您可以使用Cascading来组织多个Hadoop作业。指定要保留全局状态变量的HDFS路径,并使用虚拟内容进行初始化。在每次迭代时,读取此HDFS路径的当前内容,删除这些内容,执行任意数量的map / reduce步骤,最后执行全局reduce以更新全局状态变量。根据任务的性质,您可能需要禁用推测执行并允许重试。