我们有一个在单个节点上运行的作业,最多需要 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 模型
这是我使用 map/reduce 对其进行建模的方式,只是想确保我走在正确的道路上......
映射器
从keys.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);
}
}
Reducer
对于每个键/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()
在进行转换时调用 Web 服务是一种好习惯吗reduce()
?在 中进行这两项操作有什么好处map()
?- 我不检查重复项,
reduce()
因为 keys.txt 不包含重复键;那安全吗? - 如何控制输出文件的格式?
TextOutputFormat
看起来很有趣;我希望它像这样读...
100|foo bar|$456,098 101|bar foo|$20,980