Scala/Hadoop:指定Reducer的Context

7

在开始使用Scoobi或Scrunch之前,我想尝试使用Hadoop(0.20.1)的java绑定将WordCount移植到scala(2.9.1)上。

最初,我的代码如下:

class Map extends Mapper[LongWritable, Text, Text, IntWritable] {
  @throws[classOf[IOException]]
  @throws[classOf[InterruptedException]]
  def map(key : LongWritable, value : Text, context : Context) {
    //...

编译通过,但运行时出现错误:

java.io.IOException: Type mismatch in key from map: expected org.apache.hadoop.io.Text, recieved org.apache.hadoop.io.LongWritable

在查看了一下后,我发现问题出在我没有定义正确的map方法(应该注意到缺少了override),所以我进行了修正:

override def map(key : LongWritable, value : Text, 
  context : Mapper[LongWritable, Text, Text, IntWritable]#Context) {

然后,完美无缺,没有运行时错误。

但是我查看了作业输出后,意识到我的Reducer没有被执行。

于是我查看了我的Reducer,并注意到reduce签名与我的Mapper存在相同的问题:

class Reduce extends Reducer[Text, IntWritable, Text, IntWritable] {
  @throws[classOf[IOException]]
  @throws[classOf[InterruptedException]]
  def reduce(key : Text, value : Iterable[IntWritable], context : Context) {
    //...

因此,我猜测由于不匹配,reduce 的身份被使用。

但是当我试图更正 reduce 的签名时:

override def reduce(key: Text, values : Iterable[IntWritable], 
  context : Reducer[Text, IntWritable, Text, IntWritable]#Context) {

我现在遇到了一个编译器错误:

[ERROR] /path/to/src/main/scala/WordCount.scala:32: error: method reduce overrides nothing
[INFO]     override def reduce(key: Text, values : Iterable[IntWritable], 

所以我不确定我做错了什么。


降低 (reduce) 的签名 (signature) 应该是什么? - Daniel C. Sobral
@DanielC.Sobral:这就是我的问题。 - rampion
1个回答

11

乍一看,确保"values"是java.lang.Iterable而非scala Iterable。您可以导入java.lang.Iterable或者:

override def reduce(key: Text, values : java.lang.Iterable[IntWritable], context : Reducer[Text, IntWritable, Text, IntWritable]#Context)

2
这是完全正确的。请参考此处的示例:https://bitbucket.org/jasonbaldridge/fogbow/src/6c24fb2afda4/src/main/scala/fogbow/example/WordCount.scala - dhg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接