[HADOOP] Hadoop MapReduce를 사용하여 정렬 된 단어 수
HADOOPHadoop MapReduce를 사용하여 정렬 된 단어 수
MapReduce를 처음 접했고 Hadoop 단어 집계 예제를 완성했습니다.
이 예제에서는 단어 수의 정렬되지 않은 파일 (키 - 값 쌍 포함)을 생성합니다. 다른 MapReduce 작업을 이전 작업과 결합하여 단어 발생 횟수별로 정렬 할 수 있습니까?
해결법
-
==============================
1.간단한 단어 카운트 맵 축소 프로그램에서 우리가 얻는 결과는 단어별로 정렬됩니다. 샘플 출력은 다음과 같습니다. 애플 1 소년 30 고양이 2 개구리 20 얼룩말 1 출력되는 단어의 수를 기준으로 출력을 정렬하려면 (즉, 아래 형식으로) Apple 1 개 1 얼룩말 2 고양이 개구리 20 마리 30 소년 아래의 매퍼 (mapper)와 감속기 (reducer)를 사용하여 다른 MR 프로그램을 만들 수 있습니다. 여기서 입력은 간단한 단어 카운트 프로그램에서 얻은 결과입니다.
간단한 단어 카운트 맵 축소 프로그램에서 우리가 얻는 결과는 단어별로 정렬됩니다. 샘플 출력은 다음과 같습니다. 애플 1 소년 30 고양이 2 개구리 20 얼룩말 1 출력되는 단어의 수를 기준으로 출력을 정렬하려면 (즉, 아래 형식으로) Apple 1 개 1 얼룩말 2 고양이 개구리 20 마리 30 소년 아래의 매퍼 (mapper)와 감속기 (reducer)를 사용하여 다른 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()); } } }
-
==============================
2.Hadoop MapReduce 단어 계산 예제의 결과는 키순으로 정렬됩니다. 따라서 출력은 알파벳순으로 작성해야합니다.
Hadoop MapReduce 단어 계산 예제의 결과는 키순으로 정렬됩니다. 따라서 출력은 알파벳순으로 작성해야합니다.
Hadoop을 사용하면 WritableComparable 인터페이스를 구현하는 자체 키 객체를 만들어 compareTo 메소드를 재정의 할 수 있습니다. 이렇게하면 정렬 순서를 제어 할 수 있습니다.
발생 횟수에 따라 정렬 된 출력을 생성하려면, 말한대로 처음부터 출력을 처리하기 위해 다른 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)); } }
나는 여기에서이 예를 붙 잡았다.
아마 hashCode, equals 및 toString도 대체해야합니다.
-
==============================
3.Hadoop에서는 Map과 Reduce 단계 사이에서 정렬이 수행됩니다. 단어 발생별로 정렬하는 한 가지 방법은 아무 것도 그룹화하지 않는 사용자 지정 그룹 비교기를 사용하는 것입니다. 그러므로 줄이기위한 모든 호출은 키와 하나의 값입니다.
Hadoop에서는 Map과 Reduce 단계 사이에서 정렬이 수행됩니다. 단어 발생별로 정렬하는 한 가지 방법은 아무 것도 그룹화하지 않는 사용자 지정 그룹 비교기를 사용하는 것입니다. 그러므로 줄이기위한 모든 호출은 키와 하나의 값입니다.
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; } }
-
==============================
4.당신이 말했듯이, 한 가지 가능성은 이것을하기 위해 두 가지 일자리를 작성하는 것입니다. 첫 직업: 간단한 단어 계산 예제
당신이 말했듯이, 한 가지 가능성은 이것을하기 위해 두 가지 일자리를 작성하는 것입니다. 첫 직업: 간단한 단어 계산 예제
두 번째 직업 : 정렬 부분을합니까?
의사 코드는 다음과 같습니다.
참고 : 첫 번째 작업에서 생성 된 출력 파일은 두 번째 작업에 대한 입력입니다.
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);
이 콤퍼레이터는 감속기 측에 보내기 전에 값을 내림차순으로 정렬합니다. 따라서 감속기에서는 값을 방출합니다.
from https://stackoverflow.com/questions/2550784/sorted-word-count-using-hadoop-mapreduce by cc-by-sa and MIT license
'HADOOP' 카테고리의 다른 글
[HADOOP] 왜 하이브는 선택 부분에 명명 된 별명을 인식 할 수 없습니까? (0) | 2019.06.08 |
---|---|
[HADOOP] 하이브는에서 지원하지 않습니다. 다음 쿼리는 어떻게 작성합니까? (0) | 2019.06.08 |
[HADOOP] Hadoop : "start-all.sh"를 입력 한 후 루트 암호가 필요합니다. (0) | 2019.06.07 |
[HADOOP] Hadoop의 Sort Comparator와 Group Comparator의 차이점은 무엇입니까? (0) | 2019.06.07 |
[HADOOP] hbase는 기존 테이블을 찾을 수 없습니다. (0) | 2019.06.07 |