Java Hadoop Mapper如何发送多个值
我的映射器需要发送以下元组:Java Hadoop Mapper如何发送多个值,java,hadoop,mapper,Java,Hadoop,Mapper,我的映射器需要发送以下元组: <custID,prodID,rate> 我想将custID作为键发送给reducer,并将prodID和rate作为值一起发送给reducer,因为reduce阶段需要它们。 这样做的最佳方式是什么 public void map(Object key, Text value, Context context) throws IOException, InterruptedException { String[] co
<custID,prodID,rate>
我想将custID作为键发送给reducer,并将prodID和rate作为值一起发送给reducer,因为reduce阶段需要它们。
这样做的最佳方式是什么
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String[] col = value.toString().split(",");
custID.set(col[0]);
data.set(col[1] + "," + col[2]);
context.write(custID, data);
}
public void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
for (Text val : values) {
String[] temp = val.toString().split(",");
Text rate = new Text(temp[1]);
result.set(rate);
context.write(key, result);
}
}
public void映射(对象键、文本值、上下文)
抛出IOException、InterruptedException{
String[]col=value.toString().split(“,”);
custID.set(列[0]);
data.set(列[1]+“,”+col[2]);
context.write(custID,data);
}
公共void reduce(文本键、Iterable值、上下文)
抛出IOException、InterruptedException{
用于(文本值:值){
字符串[]temp=val.toString().split(“,”);
文本速率=新文本(临时[1]);
结果集(速率);
编写(键、结果);
}
}
我能想到的最简单的方法就是将它们合并成一个字符串:
output.collect(custID, prodID + "," + rate);
然后,如果备份到减速器上,则拆分
如果你从你的映射器中发布更多的代码,也许我们可以给出一个更好的例子
更新:也就是说,你要求的是最好的方法。最正确的方法可能是一起创建一个单独的类分组
prodID
和rate
,并将其发送。最好的方法是编写自定义可写内容
这是双值的。您可以将其更改为文本或字符串
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
/**
* @author Unmesha SreeVeni U.B
*
*/
public class TwovalueWritable implements Writable {
private double first;
private double second;
public TwovalueWritable() {
set(first, second);
}
public TwovalueWritable(double first, double second) {
set(first, second);
}
public void set(double first, double second) {
this.first = first;
this.second = second;
}
public double getFirst() {
return first;
}
public double getSecond() {
return second;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeDouble(first);
out.writeDouble(second);
}
@Override
public void readFields(DataInput in) throws IOException {
first = in.readDouble();
second = in.readDouble();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(first);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(second);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof TwovalueWritable)) {
return false;
}
TwovalueWritable other = (TwovalueWritable) obj;
if (Double.doubleToLongBits(first) != Double
.doubleToLongBits(other.first)) {
return false;
}
if (Double.doubleToLongBits(second) != Double
.doubleToLongBits(other.second)) {
return false;
}
return true;
}
@Override
public String toString() {
return first + "," + second;
}
}
从mapper中,您可以将其作为
context.write(key,new TwovalueWritable(prodID,rate));
希望这有帮助。为什么不能发送多个值?没有任何东西限制单个映射任务可以生成的键值对的数量。我尝试此解决方案(合并它们),但在reducer中使用字符串v=val.toString().split(“,”);命令来拆分字符串,我可以定期使用v[0],但是当我使用v[1]值时,我会得到一个异常“array out bounds”。您可以发布一些代码(到您的原始问题或pastebin/github摘要中)来了解您当前拥有的内容吗?您可能会发现这很有用:这并不是真正推荐的方法,因为它效率较低,将prodID和rate作为字符串传递。它还需要在reducer中进行字符串操作,这是另一个低效的地方。@RaviHTapela:如果您使用的是EclipseIDE-equals,则可以自动生成哈希代码