복붙노트

[HADOOP] Java Hadoop : 입력 파일로 가져와 각 파일의 줄 수를 출력하는 매퍼를 어떻게 만들 수 있습니까?

HADOOP

Java Hadoop : 입력 파일로 가져와 각 파일의 줄 수를 출력하는 매퍼를 어떻게 만들 수 있습니까?

저는 Hadoop에 익숙하지 않고 wordCount 예제 만 실행하도록 관리했습니다. http://hadoop.apache.org/common/docs/r0.18.2/mapred_tutorial.html

우리는 3 개의 파일이있는 폴더가 있다고 가정합니다. 각 파일에 대해 하나의 매퍼를 갖고 싶습니다.이 매퍼는 줄 수를 계산하여 감속기로 반환합니다.

감속기는 각 매퍼에서 행 수를 입력으로 가져 와서 3 개의 파일 모두에 존재하는 총 행 수를 출력으로 제공합니다.

그래서 우리가 다음의 3 가지 파일을 가지고 있다면

input1.txt
input2.txt
input3.txt

매퍼가 반환합니다.

mapper1 -> [input1.txt, 3]
mapper2 -> [input2.txt, 4]
mapper3 -> [input3.txt, 9]

감속기는

3+4+9 = 16 

간단한 자바 애플리케이션에서이 작업을 수행하여 Hadoop에서 수행하고 싶습니다. 컴퓨터가 1 대 밖에 없기 때문에 가상 분산 환경에서 실행 해보고 싶습니다.

이 일을 어떻게 성취 할 수 있습니까? 어떤 적절한 단계를 밟아야합니까?

내 코드는 아파치의 예제처럼 보일까? 나는 2 개의 정적 클래스를 가질 것인데 하나는 감속기를위한 매퍼 하나를위한 것인가? 또는 각 매퍼에 대해 하나씩 3 개의 클래스가 있어야합니까?

당신이 이것을 통해 나를 안내 해줄 수 있다면, 어떻게 해야할지 모르겠다. 그리고 나는이 물건을 다루는 몇 가지 코드를 작성하면 앞으로 더 복잡한 응용 프로그램을 작성할 수있을 것이라고 믿는다.

감사!

해결법

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

    1.sa125의 대답 외에도 각 입력 레코드에 대한 레코드를 방출하지 않고 성능을 크게 향상시킬 수 있지만 매퍼에 카운터를 누적 한 다음 매퍼 정리 메서드에서 파일 이름 및 카운트 값을 내 보냅니다.

    sa125의 대답 외에도 각 입력 레코드에 대한 레코드를 방출하지 않고 성능을 크게 향상시킬 수 있지만 매퍼에 카운터를 누적 한 다음 매퍼 정리 메서드에서 파일 이름 및 카운트 값을 내 보냅니다.

    public class LineMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
        protected long lines = 0;
    
        @Override
        protected void cleanup(Context context) throws IOException,
                InterruptedException {
            FileSplit split = (FileSplit) context.getInputSplit();
            String filename = split.getPath().toString();
    
            context.write(new Text(filename), new LongWritable(lines));
        }
    
        @Override
        protected void map(LongWritable key, Text value, Context context)
                throws IOException, InterruptedException {
            lines++;
        }
    }
    
  2. ==============================

    2.나는 당신이 0.18 버전의 문서를 사용하는 것으로 나타났습니다. 다음은 1.0.2 (최신) 링크입니다.

    나는 당신이 0.18 버전의 문서를 사용하는 것으로 나타났습니다. 다음은 1.0.2 (최신) 링크입니다.

    첫 번째 조언 - IDE (Eclipse, IDEA 등)를 사용하십시오. 공백을 채우는 것이 정말 도움이 될 것입니다.

    실제 HDFS에서는 파일의 각 부분 (다른 시스템 및 클러스터)이 어디에 있는지 알 수 없습니다. 행 X가 행 Y와 동일한 디스크에도 상주한다는 보장이 없습니다. 열 X가 다른 시스템 (HDFS가 블록으로 데이터를 분배 함, 일반적으로 각각 64MB)에 분배되지 않을 것이라는 보장은 없습니다. 즉, 동일한 매퍼가 전체 파일을 처리한다고 가정 할 수 없습니다. 당신이 확신 할 수있는 것은 각 파일이 동일한 축소 자에 의해 처리된다는 것입니다.

    감속기는 매퍼에서 보낸 키마다 고유하므로이 작업을 수행하는 방법은 매퍼에서 출력 키로 파일 이름을 사용하는 것입니다. 또한 매퍼의 기본 입력 클래스는 TextInputFormat입니다. 즉, 각 매퍼가 자체적으로 전체 행을 수신합니다 (LF 또는 CR로 종료 됨). 그런 다음 매퍼 (mapper)에서 파일 이름과 숫자 1 (또는 계산과 관련이없는)을 내보낼 수 있습니다. 그런 다음 감속기에서 루프를 사용하여 파일 이름이 수신 된 횟수를 계산합니다.

    public static class Map extends Mapper<IntWritable, Text, Text, Text> {
    
      public void map(IntWritable key, Text value, Context context) {
        // get the filename
        InputSplit split = context.getInputSplit();
        String fileName = split.getPath().getName();
    
        // send the filename to the reducer, the value
        // has no meaning (I just put "1" to have something)
        context.write( new Text(fileName), new Text("1") );
      }
    
    }
    
    public static class Reduce extends Reducer<Text, Text, Text, Text> {
    
      public void reduce(Text fileName, Iterator<Text> values, Context context) {
        long rowcount = 0;
    
        // values get one entry for each row, so the actual value doesn't matter
        // (you can also get the size, I'm just lazy here)
        for (Text val : values) {
          rowCount += 1;
        }
    
        // fileName is the Text key received (no need to create a new object)
        context.write( fileName, new Text( String.valueOf( rowCount ) ) );
      }
    
    }
    

    wordcount 예제와 거의 같은 드라이버를 사용할 수 있습니다. 새로운 mapreduce API를 사용 했으므로 JobConf 대신 Job (JobConf 대신 Job)을 조정해야합니다. 이것은 내가 읽었을 때 정말 도움이되었습니다.

    MR 출력은 각 파일 이름과 행 개수만큼됩니다.

    input1.txt    3
    input2.txt    4
    input3.txt    9
    

    모든 파일의 총 줄 수를 계산하려면 파일 이름이 아닌 모든 매퍼에서 동일한 키를 내보내는 것만으로 충분합니다. 이렇게하면 행 수를 모두 처리 할 수있는 감속기가 하나만 있습니다.

    // no need for filename
    context.write( new Text("blah"), new Text("1") );
    

    또한 파일 단위 행 개수의 출력을 처리하거나 다른 멋진 작업을 수행 할 작업을 연결할 수 있습니다. 이는 당신에게 달려 있습니다.

    일부 상용구 코드를 남겨 뒀지 만 기본은 있습니다. 내가 메모리에서 이것을 대부분 입력했기 때문에 나에게 확인해라. :)

    희망이 도움이!

  3. from https://stackoverflow.com/questions/10367389/java-hadoop-how-can-i-create-mappers-that-take-as-input-files-and-give-an-outpu by cc-by-sa and MIT license