我们有一个在单个节点上运行的工作,需要长达 40m 才能完成,而使用 M/R,我们希望将其降低到不到 2m,但我们不确定流程的哪些部分进入map()
和reduce()
。
当前流程:
对于密钥列表,请为每个密钥调用 Web 服务并获取 xml 响应;将 XML 转换为竖线分隔格式;最后输出单个文件...
def keys = 100..9999
def output = new StringBuffer()
keys.each(){ key ->
def xmlResponse = callRemoteService( key)
def transformed = convertToPipeDelimited( xmlResponse)
output.append( transformed)
}
file.write( output)
映射/归约模型
这是我如何使用map/reduce对其进行建模的方式,只是想确保我走在正确的道路上......
映射
钥匙从钥匙中抽出.txt;我为每个密钥调用远程服务并存储密钥/xml 对...
public static class XMLMapper extends Mapper<Text, Text, Text, Text> {
private Text xml = new Text();
public void map(Text key, Text value, Context context){
String xmlResponse = callRemoteService( key)
xml.set( xmlResponse)
context.write(key, xml);
}
}
还原剂
对于每个键/xml 对,我将 xml 转换为管道分隔的格式,然后写出结果......
public static class XMLToPipeDelimitedReducer extends Reducer<Text,Text,Text,Text> {
private Text result = new Text();
public void reduce(Text key, Iterable<Text> values, Context context ) {
String xml = values.iterator().next();
String transformed = convertToPipeDelimited( xml);
result.set( transformed);
context.write( key, result);
}
}
问题
map()
在执行在reduce()
中转换 ;在 中执行这两项操作的任何好处map()
?- 我不检查
reduce()
中的重复项,因为键.txt不包含重复的键;这样安全吗? - 如何控制输出文件的格式?
TextOutputFormat
看起来很有趣;我希望它读起来像这样...
100|foo bar|$456,098 101|bar foo|$20,980
您应该在映射端进行转换,原因如下:
- 从 xml 转换为管道分隔将减少序列化和传输到化简器的数据量。
- 您将运行多个映射作业,但只有一个归约作业,因此您希望转换映射端以利用该并行性。
- 由于所有工作都是在映射端进行的,因此您只需使用提供的IdentityReducer,而不必为此编写自己的代码。
,你需要使用一个化简器;map-reduce为每个化简器生成一个输出文件。
如果您确定没有重复的键,那么是的,忽略重复的减少端应该是安全的。
我相信 TextOutputFormat 默认情况下会将您的(键、值(对作为制表符分隔的字符串写入文件,因此不完全是您想要的格式。请参阅此处了解如何更改此设置。
您的Web服务将成为这里的一个限制因素。假设您希望 40 分钟的作业在 2 分钟内运行,则可能需要从中读取 40 个左右的地图作业。它可以处理 40 个并发读取器吗?
你的另一个限制因素将是减少方面。假设你想要一个按键排序的输出文件,你将不得不使用一个化简器,它必须对所有输入进行排序,这可能需要一点点。
一旦你的代码工作,你必须运行一些实验,看看哪些设置能给你一个合理的运行时间。祝你好运。