我正在编写一个Hadoop应用程序以一定的分辨率计算地图数据。我的输入文件是地图的图块,根据QuadTile原则命名。我需要对它们进行子采样,并将它们拼接在一起,直到我有一个更高级别的区块,覆盖更大的区域,但分辨率更低。就像在谷歌地图中缩小一样。
目前我的Mapper子样本瓷砖和我的减速器将瓷砖组合在一定水平并形成一层的瓷砖。所以这么好。但是根据我需要的哪个图块,我需要重复这些图并将步骤减少x次,这是迄今为止我无法做到的。
最好的方法是什么?是否可以在没有明确地将tile保存在某个临时目录中并在那些临时目录上启动新的mapreduce作业,直到我得到我想要的为止?我认为完美的解决方案大致类似于'while(context.hasMoreThanOneKey()){iterate mapreduce}'。
在回答之后,我现在写了一个TileJob类来扩展Job。但是,mapreduc仍然没有链接。你能告诉我我做错了吗?
public boolean waitForCompletion(boolean verbose) throws IOException, InterruptedException, ClassNotFoundException{
if(desiredkeylength != currentinputkeylength-1){
System.out.println("In loop, setting input at " + tempout);
String tempin = tempout;
FileInputFormat.setInputPaths(this, tempin);
tempout = (output + currentinputkeylength + "/");
FileOutputFormat.setOutputPath(this, new Path(tempout));
System.out.println("Setting output at " + tempout);
currentinputkeylength--;
Configuration conf = new Configuration();
TileJob job = new TileJob(conf);
job.setJobName(getJobName());
job.setUpJob(tempin, tempout, tiletogenerate, currentinputkeylength);
return job.waitForCompletion(verbose);
}else{
//desiredkeylength == currentkeylength-1
System.out.println("In else, setting input at " + tempout);
String tempin = tempout;
FileInputFormat.setInputPaths(this, tempin);
tempout = output;
FileOutputFormat.setOutputPath(this, new Path(tempout));
System.out.println("Setting output at " + tempout);
currentinputkeylength--;
Configuration conf = new Configuration();
TileJob job = new TileJob(conf);
job.setJobName(getJobName());
job.setUpJob(tempin, tempout, tiletogenerate, currentinputkeylength);
currentinputkeylength--;
return super.waitForCompletion(verbose);
}
}
答案 0 :(得分:1)
通常通过使用配置作业,配置和格式类型(输入和输出)的驱动程序类main方法来启动mapreduce步骤。一切准备就绪后,主方法调用Job :: waitForCompletion()提交作业并等待作业完成后再继续。
您可以将一些逻辑包装在一个循环中,该循环重复调用Job :: waitForCompletion()直到满足您的条件。您可以使用计数器实施标准。将逻辑放入reduce()方法,以设置或增加具有键数的计数器。您在驱动程序类中的循环可以从Job实例获取该(分布式)计数器的值,并使用该值对while表达式进行编码。
您使用的文件位置取决于您。在此驱动程序循环中,您可以更改输入和输出的文件位置,或保持它们相同。
我应该补充一点,你应该继续在循环中创建一个新的Job和Configuration实例。我不知道在这种情况下这些对象是可重用的。
public static void main(String[] args) {
int keys = 2;
boolean completed = true;
while (completed & (keys > 1)) {
Job job = new Job();
// Do all your job configuration here
completed = job.waitForCompletion();
if (completed) {
keys = job.getCounter().findCounter("Total","Keys").getValue();
}
}
}