복붙노트

[HADOOP] 파일 이름의 재발없이 hadoop 역 색인

HADOOP

파일 이름의 재발없이 hadoop 역 색인

내가 출력물에 가지고있는 것은 :

단어, 파일 ----- ------ wordx Doc2, Doc1, Doc1, Doc1, Doc1, Doc1, Doc1, Doc1

내가 원하는 건 :

단어, 파일 ----- ------ wordx Doc2, Doc1

public static class LineIndexMapper extends MapReduceBase
        implements Mapper<LongWritable, Text, Text, Text> {

    private final static Text word = new Text();
    private final static Text location = new Text();

    public void map(LongWritable key, Text val,
            OutputCollector<Text, Text> output, Reporter reporter)
            throws IOException {
        FileSplit fileSplit = (FileSplit) reporter.getInputSplit();
        String fileName = fileSplit.getPath().getName();
        location.set(fileName);

        String line = val.toString();
        StringTokenizer itr = new StringTokenizer(line.toLowerCase());
        while (itr.hasMoreTokens()) {
            word.set(itr.nextToken());
            output.collect(word, location);
        }
    }
}

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

    public void reduce(Text key, Iterator<Text> values,
            OutputCollector<Text, Text> output, Reporter reporter)
            throws IOException {

        boolean first = true;
        StringBuilder toReturn = new StringBuilder();
        while (values.hasNext()) {
            if (!first) {
                toReturn.append(", ");
            }
            first = false;
            toReturn.append(values.next().toString());
        }

        output.collect(key, new Text(toReturn.toString()));
    }
}

최고의 성능을 위해 - 반복 파일 이름을 어디에서 건너 뛰어야합니까? 지도, 축소 또는 둘 다? ps : 저는 MR 작업을 작성하는 초심자이며 또한 제 질문으로 프로그래밍 논리를 파악하려고합니다.

해결법

  1. ==============================

    1.Reducer에서 중복 제품 만 제거 할 수 있습니다. 이렇게하려면 중복을 허용하지 않는 집합을 사용할 수 있습니다.

    Reducer에서 중복 제품 만 제거 할 수 있습니다. 이렇게하려면 중복을 허용하지 않는 집합을 사용할 수 있습니다.

    public void reduce(Text key, Iterator<Text> values,
            OutputCollector<Text, Text> output, Reporter reporter)
            throws IOException {
    
        // Text's equals() method should be overloaded to make this work
        Set<Text> outputValues = new HashSet<Text>();
    
        while (values.hasNext()) {
          // make a new Object because Hadoop may mess with original
          Text value = new Text(values.next());
    
          // takes care of removing duplicates
          outputValues.add(value);
        }
    
        boolean first = true;
        StringBuilder toReturn = new StringBuilder();
        Iterator<Text> outputIter = outputValues.iter();
        while (outputIter.hasNext()) {
            if (!first) {
                toReturn.append(", ");
            }
            first = false;
            toReturn.append(outputIter.next().toString());
        }
    
        output.collect(key, new Text(toReturn.toString()));
    }
    

    편집 : Chris의 의견에 따라 Set에 값의 사본을 추가합니다.

  2. ==============================

    2.로컬 맵 집계를 수행하고 결합기를 도입하여 성능을 향상시킬 수 있습니다. 기본적으로 맵퍼와 리듀서간에 전송되는 데이터의 양을 줄이고 싶습니다.

    로컬 맵 집계를 수행하고 결합기를 도입하여 성능을 향상시킬 수 있습니다. 기본적으로 맵퍼와 리듀서간에 전송되는 데이터의 양을 줄이고 싶습니다.

    로컬 맵 집계는지도 쌍 (또는 세트)과 같은 LRU를 유지 관리하는 개념입니다. 귀하의 경우에는 현재 매퍼 문서에 대한 단어 집합 (지도 당 하나의 문서가 있다고 가정). 이 방법으로 집합에서 단어를 검색 할 수 있으며 집합에 이미 해당 단어가 포함되어 있지 않으면 (즉 항목을 아직 출력하지 않았 음을 나타냄) K, V 쌍만 출력 할 수 있습니다. 세트에 단어가 포함되어 있지 않으면 docid pair라는 단어를 출력하고 단어로 세트를 업데이트하십시오.

    세트 get이 너무 큰 경우 (5000 또는 10000 항목), 클리어하고 다시 시작합니다. 이렇게하면 매퍼에서 출력되는 값의 수가 극적으로 표시됩니다 (값 도메인이나 값 집합이 작 으면 단어가 좋은 예입니다).

    또한 결합기 단계에서 감속기 로직을 ​​도입 할 수도 있습니다.

    일단 경고의 최종 경고 - 세트에 키 / 값 객체를 추가하는 것에주의를 기울여야합니다 (예 : Matt D의 답변). hadoop은 객체를 재사용합니다. 그래서 추가하면 예기치 않은 결과가 발생하더라도 놀라지 마십시오. 참조는 항상 객체의 복사본을 만듭니다.

    로컬지도 집계에 대한 기사 (단어 집계 예제)가 유용 할 수 있습니다.

  3. from https://stackoverflow.com/questions/10305435/hadoop-inverted-index-without-recurrence-of-file-names by cc-by-sa and MIT license