2010-03-31 3 views
9

MapReduce를 처음 접했고 Hadoop 단어 수를 완료했습니다.Hadoop MapReduce를 사용한 정렬 된 단어 수

이 예제에서는 워드 수가없는 정렬되지 않은 파일 (키 - 값 쌍 포함)을 생성합니다. 다른 MapReduce 작업을 이전 작업과 결합하여 단어 발생 횟수별로 정렬 할 수 있습니까?

+0

이 질문은 꽤 오래되었으므로 나는 단지 코멘트 만 할 것입니다 : 돼지에서 아주 쉽게 할 수 있습니다 : a = load '/ out/wordcount'as (word : chararray, num : int); b = 순서로 a를 num으로; b를 '/ 출력/단어 개수 - 정렬'에 저장합니다. – wlk

답변

0

Hadoop MapReduce 단어 계산 예제의 결과는 키순으로 정렬됩니다. 따라서 출력은 알파벳순으로 이루어져야합니다.

Hadoop을 사용하면 compareTo 메서드를 재정의 할 수있는 WritableComparable 인터페이스를 구현하는 자체 키 객체를 만들 수 있습니다. 이렇게하면 정렬 순서를 제어 할 수 있습니다.

발생 횟수별로 정렬 된 출력을 만들려면 말한대로 처음부터 출력을 처리하기 위해 다른 MapReduce 작업을 추가해야 할 것입니다. 이 두 번째 일은 매우 간단 할 것이며 감축 단계조차 필요하지 않을 수도 있습니다. 단어와 빈도를 감싸기 위해 자신 만의 Writable 키 객체를 구현하면됩니다. 사용자 정의 쓰기는 다음과 같은 :

public class MyWritableComparable implements WritableComparable { 
     // Some data 
     private int counter; 
     private long timestamp; 

     public void write(DataOutput out) throws IOException { 
     out.writeInt(counter); 
     out.writeLong(timestamp); 
     } 

     public void readFields(DataInput in) throws IOException { 
     counter = in.readInt(); 
     timestamp = in.readLong(); 
     } 

     public int compareTo(MyWritableComparable w) { 
     int thisValue = this.value; 
     int thatValue = ((IntWritable)o).value; 
     return (thisValue < thatValue ? -1 : (thisValue==thatValue ? 0 : 1)); 
     } 
    } 

내가 here에서이 예제를 잡았다.

hashCode, equalstoString도 대체해야합니다.

+0

주어진 예제와 관련된 compareTo 메소드가 있습니까? –

0

Hadoop에서는 정렬 단계와 축소 단계 사이에서 정렬이 수행됩니다. 단어 발생별로 정렬하는 한 가지 방법은 그룹화하지 않는 사용자 지정 그룹 비교기를 사용하는 것입니다. 그러므로 줄이기위한 모든 호출은 키와 하나의 값입니다.

public class Program { 
    public static void main(String[] args) { 

     conf.setOutputKeyClass(IntWritable.class); 
     conf.setOutputValueClass(Text.clss); 
     conf.setMapperClass(Map.class); 
     conf.setReducerClass(IdentityReducer.class); 
     conf.setOutputValueGroupingComparator(GroupComparator.class); 
     conf.setNumReduceTasks(1); 
     JobClient.runJob(conf); 
    } 
} 

public class Map extends MapReduceBase implements Mapper<Text,IntWritable,IntWritable,Text> { 

    public void map(Text key, IntWritable value, OutputCollector<IntWritable,Text>, Reporter reporter) { 
     output.collect(value, key); 
    } 
} 

public class GroupComaprator extends WritableComparator { 
    protected GroupComparator() { 
     super(IntWritable.class, true); 
    } 

    public int compare(WritableComparable w1, WritableComparable w2) { 
     return -1; 
    } 
} 
+0

compareTo, 비교하지 않음 ... – minghan

+0

@minghan nope, ['Comparator'] (http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html)는'compare'가 필요합니다 – asgs

1

간단한 단어 카운트 맵 축소 프로그램에서 우리가 얻는 결과는 단어별로 정렬됩니다. 샘플 출력이 될 수 있습니다
애플 1
보이 (30)
고양이 2
개구리 20
얼룩말 1
당신이 출력 형식
다음 단어의 occrance, 즉의 수를 기준으로 정렬하려면 1 애플
1 얼룩말
2 고양이
(20) 개구리
(30) 보이
당신은 MAPP 이하로 사용하여 다른 MR 프로그램을 만들 수 있습니다 어와 감속기 어디 간단한 단어 카운트 프로그램에서 얻은 출력 될 입력됩니다.

class Map1 extends MapReduceBase implements Mapper<Object, Text, IntWritable, Text> 
{ 
    public void map(Object key, Text value, OutputCollector<IntWritable, Text> collector, Reporter arg3) throws IOException 
    { 
     String line = value.toString(); 
     StringTokenizer stringTokenizer = new StringTokenizer(line); 
     { 
      int number = 999; 
      String word = "empty"; 

      if(stringTokenizer.hasMoreTokens()) 
      { 
       String str0= stringTokenizer.nextToken(); 
       word = str0.trim(); 
      } 

      if(stringTokenizer.hasMoreElements()) 
      { 
       String str1 = stringTokenizer.nextToken(); 
       number = Integer.parseInt(str1.trim()); 
      } 

      collector.collect(new IntWritable(number), new Text(word)); 
     } 

    } 

} 


class Reduce1 extends MapReduceBase implements Reducer<IntWritable, Text, IntWritable, Text> 
{ 
    public void reduce(IntWritable key, Iterator<Text> values, OutputCollector<IntWritable, Text> arg2, Reporter arg3) throws IOException 
    { 
     while((values.hasNext())) 
     { 
      arg2.collect(key, values.next()); 
     } 

    } 

} 
+0

그래서 ...이 코드를 원래의 코드 아래에 추가해야합니까? 좀 더 구체적으로 말해 줄 수 있니? 나는 새로운 자바와 새로운 hadoop ... 여기에 내 코드 : http://stackoverflow.com/questions/28785337/how-to-re-arrange-wordcount-hadoop-output-result-and-sort-them -by-value – JPC

+0

또한이 오류가 발생합니다. "유형 매퍼 는 Map1의 수퍼 인터페이스가 될 수 없으며 수퍼 인터페이스는" – JPC

+0

"인터페이스 여야합니다. 단어별로 정렬됩니다. " 그건 사실이 아니야. – vefthym

0

당신이 말했듯이, 하나의 가능성은 이렇게하기 위해 두 가지 작업을 작성하는 것입니다. 첫 번째 직업 : 간단한 단어 수 예

두 번째 작업 : 정렬 부분을 수행합니까?

의사 코드가 될 수있다 :

참고 : 첫 번째 작업에 의해 생성 된 출력 파일이 두 번째 작업

Mapper2(String _key, Intwritable _value){ 
    //just reverse the position of _value and _key. This is useful because reducer will get the output in the sorted and shuffled manner. 
    emit(_value,_key); 
    } 

    Reduce2(IntWritable valueofMapper2,Iterable<String> keysofMapper2){ 
//At the reducer side, all the keys that have the same count are merged together. 
     for each K in keysofMapper2{ 
     emit(K,valueofMapper2); //This will sort in ascending order. 
     } 

    } 

에 대한 입력됩니다 정렬 할 수도있는 내림차순 트릭을 수행 할 별도의 비교기 클래스를 작성하는 것이 가능합니다. 감속기 측에 전송하기 전에 내림차순으로 값을 정렬합니다

Job.setComparatorclass(Comparator.class); 

이 비교기 : 은 작업 내부 비교기를 포함합니다. 그래서 감속기에, 당신은 방금 값을 방출.

관련 문제