2017-05-23 8 views
1

맵퍼 및 감속기를 설정하지 않고 다른 프로그램에서 매개 변수를 설정하지 않는 hadoop map-reduce 프로그램을 작성 중입니다. 저는 작업이 출력과 동일한 출력을 출력 파일에 보낼 것이라고 가정했습니다. 하지만 내가 그 탭 (아마)에 의해 구분 된 모든 라인 출력 파일에 더미 정수 값을 인쇄하는 것으로 나타났습니다. 여기 Map-reduce 출력 파일에서 알 수없는 정수 값 가져 오기

내 코드입니다 :

import org.apache.hadoop.conf.Configured; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 
import org.apache.hadoop.util.Tool; 
import org.apache.hadoop.util.ToolRunner; 

public class MinimalMapReduce extends Configured implements Tool { 

    public int run(String[] args) throws Exception { 

     Job job = new Job(getConf()); 
     job.setJarByClass(getClass()); 
     FileInputFormat.addInputPath(job, new Path(args[0])); 
     FileOutputFormat.setOutputPath(job, new Path(args[1])); 

     return job.waitForCompletion(true) ? 0 : 1; 
    } 

    public static void main(String[] args) { 
     String argg[] = {"/Users/***/Documents/hadoop/input/input.txt", 
          "/Users/***/Documents/hadoop/output_MinimalMapReduce"}; 
     try{ 
      int exitCode = ToolRunner.run(new MinimalMapReduce(), argg); 
      System.exit(exitCode); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

그리고 여기에 입력 :

2011 22 
2011 25 
2012 40 
2013 35 
2013 38 
2014 44 
2015 43 

그리고 여기에 출력됩니다 :

0 2011 22 
8 2011 25 
16 2012 40 
24 2013 35 
32 2013 38 
40 2014 44 
48 2015 43 

내가 같은 OUPUT 등을 얻을 수있는 방법 입력?

+2

이것은 매퍼를 지정하지 않아도 'IdentityMapper'가 항상 실행되기 때문입니다. 각 줄 앞에 _unknown 정수 _는 파일 시작 부분에서 해당 줄의 오프셋입니다. – philantrovert

+0

@philantrovert 나는 이것을 해답으로 올리겠다. –

+0

@BinaryNerd 그것, 선생님. 당신이 그것을 upvote 있는지 확인하십시오. 나는 너를 계속 지켜 볼거야;) – philantrovert

답변

0

나는 @ philantrovert의 대답에 동의하지만 여기에 내가 발견 한 세부 사항이있다. Hadoop- The Definitive Guide에 따르면 행 번호에 오프셋을 더하는 것은 TextInputFormat입니다.다음은 TextInputFormat에 대한 설명서입니다.

TextInputFormat이 기본 InputFormat입니다. 각 레코드는 입력 행입니다. LongWritable의 키는, 행의 선두의 파일 내의 바이트 오프셋 (offset)입니다. 이 값은 행 종료 자 (예 : 개행 또는 캐리지 리턴)를 제외한 행의 내용이며 Text 객체로 패키지됩니다. 그래서, 파일은 다음과 같은 텍스트가 포함 된 :

On the top of the Crumpetty Tree 
The Quangle Wangle sat, 
But his face you could not see, 
On account of his Beaver Hat. 

이 네 개의 레코드 중 하나 분할로 나누어진다. 기록은 다음과 같은 키 - 값 쌍으로 해석됩니다

(0, On the top of the Crumpetty Tree) 
(33, The Quangle Wangle sat,) 
(57, But his face you could not see,) 
(89, On account of his Beaver Hat.) 

분명히 키가 행 번호가 없습니다. 이것은 파일이 라인, 경계가 아닌 바이트 단위로 분할된다는 점에서 일반적으로 구현하는 것이 불가능합니다. 분할은 독립적으로 처리됩니다. 줄 번호는 실제로 순차적 인 개념입니다. 당신이 그들을 소비 할 때 줄 수를 유지해야하므로 분할 내에서 라인 번호를 알 수는 있지만 파일 내에서는 불가능합니다.

그러나 각 줄의 파일 내 오프셋은 다른 줄과는 독립적으로 각 줄에 알려져 있습니다. 각 줄은 이전 줄의 크기를 알고 분할의 오프셋에이 줄을 추가하여 전역 파일을 만듭니다 오프셋. 오프셋은 대개 각 행에 대해 고유 한 식별자가 필요한 응용 프로그램에 충분합니다. 파일 이름과 결합하면 파일 시스템 내에서 고유합니다. 물론, 모든 라인이 고정 폭이라면, 라인 수를 계산하는 것은 단순히 오프셋을 폭으로 나눈 값입니다.

2

나는 그래서 작업 당신은 그 가정에서 정확 출력 파일

에 입력과 동일한 출력을 보낼 것이라고 가정했다. 기술적으로 파일에있는 모든 것을 출력으로 얻고 있습니다. 매퍼와 리듀서는 키 - 값 쌍을 입력으로 사용합니다.

매퍼에 대한 입력은 파일의 입력 분할이고 축소기에 대한 입력은 매퍼에서 출력됩니다.

하지만 난이 더미 정수은 처음부터 그 라인의 오프셋 (offset)하지만 아무것도 그것이 탭

로 구분하여 각 라인 출력 파일에 일부 더미 정수 값을 인쇄하는 것을 발견 한 것은 파일의 각 행은 [4 DIGITS]<space>[2 DIGITS]<new-line>으로 구성되어 있으므로 오프셋은 8 개의 배수입니다.

왜 매퍼 또는 감속기를 정의하지 않았기 때문에이 오프셋을 얻고 있습니까? 매퍼가 항상 실행되어 각 줄을 오프셋에 매핑하는 작업을 수행하고 IdentityMapper이라고합니다.

어떻게 입력과 동일한 출력을 얻을 수 있습니까?

맵퍼를 정의하고 입력 라인을 출력에 매핑하고 오프셋을 제거 할 수 있습니다. 위의 코드에서

public void map(Object key, Text value, Context context 
        ) throws IOException, InterruptedException { 
    // Some cool logic here 
} 

key더미 정수 값 즉 오프셋을 포함한다. value에는 한 번에 하나씩 각 행의 값이 들어 있습니다. context.write 함수를 사용하여 value으로 코드를 작성한 다음 감속기를 사용하지 않고 job.setNumReduceTasks(0)을 설정하여 원하는 출력을 얻을 수 있습니다.