2012-02-08 50 views
0

在试图了解Hadoop的,我在练从书“的Hadoop在行动”查找最-K记录数据集中

数据集样品未解决的问题编程:

3070801,1963, 1096 ,,“BE”,“”,, 1,,269,6,69,,1,0,,,,,,,, 3070802,1963,1096 ,,“US”,“TX”,, 1 “2,6,63,0”,,,,,,,,, 3070803,1963,1096“US”,“IL”,, 1,2,6,63,9,...,0.3704 ,,,,,,, 3070804,1963,1096 ,,“US”,“OH”,, 1,2,6,63,,3,,0.6667 ,,,,,,, 3070805,1963, 1096 ,, “美国”, “CA” ,, 1,2,6,63,1,0 ,,,,,, , 3070806,1963,1096 ,,“US”,“PA”,, 1,2,6,63,0,0 ,,,,,,,,, 3070807,1963,1096,“US”, “OH”,, 1,,623,3,39,,3,,0.4444 ,,,,,,, 3070808,1963,1096 ,,“US”,“IA”,1,,623,3, 39,,4,,0.375 ,,,,,,, 3070809,1963,1096 ,,“US”,“AZ”,, 1,4,6,65,,0 ,,,,,,,, , 3070810,1963,1096 ,, “美国”, “IL” ,, 1,4,6,65,3,,0.4444 ,,,,,,,

地图功能

public static class MapClass extends MapReduceBase implements Mapper<Text, Text, IntWritable, Text> { 
     private int maxClaimCount = 0; 
     private Text record = new Text(); 

     public void map(Text key, Text value, OutputCollector<IntWritable, Text> output, Reporter reporter) throws IOException { 
      String claim = value.toString().split(",")[7]; 
      //if (!claim.isEmpty() && claim.matches("\\d")) { 
      if (!claim.isEmpty()) { 
       int claimCount = Integer.parseInt(claim); 
       if (claimCount > maxClaimCount) { 
        maxClaimCount = claimCount; 
        record = value; 
        output.collect(new IntWritable(claimCount), value); 
       } 
//    output.collect(new IntWritable(claimCount), value); 
      } 
     } 

    } 

降低功能

public static class Reduce extends MapReduceBase implements Reducer<IntWritable, Text, IntWritable, Text> { 

    public void reduce(IntWritable key, Iterator<Text> values, OutputCollector<IntWritable, Text> output, Reporter reporter) throws IOException { 
      output.collect(key, values.next()); 
    } 
} 

命令来运行:

hadoop jar ~/Desktop/wc.jar com/hadoop/patent/TopKRecords -Dmapred.map.tasks=7 ~/input ~/output 

要求:
- 基于第九列值,找到数据集上-K记录(比如7)

问题:
- 由于只有7条记录是neede d我可运行七个map任务,并确保我得到的最高数量记录作为maxClaimCountrecord
- 我不知道如何收集只是最大记录,使每个地图发出只有一个输出

我该怎么办那?

回答

3

这是一个更新的答案。所有评论都不适用于它,因为它们基于原始(不正确)的答案。


映射器应该只输出

output.collect(new IntWritable(claimCount), value); 

没有任何比较。结果将根据索赔计数进行排序并传递给减速器。

在Reducer中使用一些优先级队列来获得前7个结果。

+0

的。由于只有一个降低,如果地图的输出发出的结果是不够的,适合想在记忆中,在这种情况下可能不会发生结果,对吧? – daydreamer 2012-02-08 22:32:15

+0

每张地图只会发出7条记录。我认为你应该没问题。 – 2012-02-08 22:33:40

+0

我们怎么能这么肯定,有7个地图任务可能会得到随机的数据块,因此每个split可能会发出7个以上的记录。在当前运行中,我得到264条记录,远远超过49条记录 – daydreamer 2012-02-08 22:35:24

0

您可以使用TreeMap,它以排序的方式存储密钥。映射器将

public Mapper() { 
    TreeMap<String, String> set = new TreeMap<String, String>(); 
    Void map(object key, Text value){ 
    Set.put("get key", value); 
    If(set.size > 7) { 
     Set.removeFirst() 
    } 

    } 

Public void cleanup(){ 
    While(Entry<string, string> entry : map.entrySet()) { 
    Conetext.write(entry.key, entry.value); 
    } 
}} 
0

您可以使用前k设计模式的更多详情,请参阅以下博客 Findin Top K records in Mapreduce

+0

尽管这个链接可能回答这个问题,但最好在这里包含答案的重要部分,并提供供参考的链接。如果链接页面更改,则仅链接答案可能会失效。 – ZygD 2015-03-31 20:38:47