복붙노트

[HADOOP] HDFS 파일을 입력하고 출력 파일을 HDFS에 저장하는 매퍼 또는 감속기에서 외부 프로그램을 실행하는 방법은 무엇입니까?

HADOOP

HDFS 파일을 입력하고 출력 파일을 HDFS에 저장하는 매퍼 또는 감속기에서 외부 프로그램을 실행하는 방법은 무엇입니까?

필자는 파일을 입력으로 사용하고 출력 파일을 제공하는 외부 프로그램을 가지고 있습니다.

     //for example 
     input file: IN_FILE
     output file: OUT_FILE

    //Run External program 
     ./vx < ${IN_FILE} > ${OUT_FILE}

HDFS에서 입력 및 출력 파일을 모두 원합니다.

나는 8 개의 노드를 갖는 클러스터를 가지고있다. 그리고 나는 각각 8 개의 입력 파일을 가지고있다.

    //1 input file :       1.txt 
           1:0,0,0
    //2 input file :       2.txt 
           2:0,0,128
    //3 input file :       3.txt 
           3:0,128,0
    //5 input file :       4.txt 
           4:0,128,128
    //5 input file :       5.txt 
           5:128,0,0
    //6 input file :       6.txt 
           6:128,0,128
    //7 input file :       7.txt 
           7:128,128,0
    //8 input file :       8.txt 
           8:128,128,128

KeyValueTextInputFormat을 사용하고 있습니다.

               key :file name
               value: initial coordinates

예를 들어 5 번째 파일

              key :5
              value:128,0,0

각지도 작업은 초기 좌표에 따라 엄청난 양의 데이터를 생성합니다.

이제 각 맵 작업에서 외부 프로그램을 실행하고 출력 파일을 생성하려고합니다.

하지만 HDFS에서 파일을 사용하는 방법을 혼동합니다.

         I can use zero reducer and create file in HDFS 

         Configuration conf = new Configuration();
         FileSystem fs = FileSystem.get(conf);
         Path outFile;
         outFile = new Path(INPUT_FILE_NAME);
         FSDataOutputStream out = fs.create(outFile);

         //generating data ........ and writing to HDFS 
          out.writeUTF(lon + ";" + lat + ";" + depth + ";");

파일을 로컬 디렉토리에 저장하지 않고 HDFS 파일로 외부 프로그램을 실행하는 방법을 혼동합니다.

  with  dfs -get 

MR을 사용하지 않고 다음과 같이 쉘 스크립트로 결과를 얻고 있습니다.

#!/bin/bash

if [ $# -lt 2 ]; then
    printf "Usage: %s: <infile> <outfile> \n" $(basename $0) >&2
          exit 1
fi

IN_FILE=/Users/x34/data/$1
OUT_FILE=/Users/x34/data/$2                     

cd "/Users/x34/Projects/externalprogram/model/"

./vx < ${IN_FILE} > ${OUT_FILE}

paste ${IN_FILE} ${OUT_FILE} | awk '{print $1,"\t",$2,"\t",$3,"\t",$4,"\t",$5,"\t",$22,"\t",$23,"\t",$24}' > /Users/x34/data/combined
if [ $? -ne 0 ]; then
    exit 1
fi                      

exit 0

그런 다음에

         ProcessBuilder pb = new ProcessBuilder("SHELL_SCRIPT","in", "out"); 
         Process p = pb.start();

내가 hadoop 스트리밍이나 외부 프로그램을 실행하는 다른 방법을 사용하는 방법을 생각해 주셔서 감사합니다. 추가 처리를 위해 HDFS에 INPUT 및 OUTPUT 파일을 모두 넣고 싶습니다.

도와주세요

해결법

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

    1.따라서 외부 프로그램이 hdfs를 인식하거나 읽는 방법을 알지 못한다면, java에서 파일을로드하여 직접 입력으로 전달해야합니다.

    따라서 외부 프로그램이 hdfs를 인식하거나 읽는 방법을 알지 못한다면, java에서 파일을로드하여 직접 입력으로 전달해야합니다.

    Path path = new Path("hdfs/path/to/input/file");
    FileSystem fs = FileSystem.get(configuration);
    FSDataInputStream fin = fs.open(path);
    ProcessBuilder pb = new ProcessBuilder("SHELL_SCRIPT");
    Process p = pb.start();
    OutputStream os = p.getOutputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(fin));
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
    
    String line = null;
    while ((line = br.readLine())!=null){
        writer.write(line);
    }
    

    반대로 출력 할 수 있습니다. 프로세스에서 InputStream을 가져 와서 FSDataOutputStream을 만들어 hdfs에 기록하십시오.

    본질적으로이 두 가지를 가진 프로그램은 HDFS를 입력 및 출력으로 다시 HDFS로 변환하는 어댑터가됩니다.

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

    2.Hadoop Streaming을 다음과 같이 구현할 수 있습니다.

    Hadoop Streaming을 다음과 같이 구현할 수 있습니다.

    $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
    -input myInputDirs \
    -output myOutputDir \
    -mapper myPythonScript.py \
    -reducer /bin/wc \
    -file myPythonScript.py \
    -file myDictionary.txt
    

    몇 가지 예는 https://hadoop.apache.org/docs/r1.0.4/streaming.pdf를 참조하십시오.

    또한 좋은 기사 : http://princetonits.com/blog/technology/hadoop-mapreduce-streaming-using-bash-script/

    Hadoop 스트리밍은 Hadoop 배포와 함께 제공되는 유틸리티입니다. 이 유틸리티를 사용하면 매퍼 및 / 또는 감속기로 실행 파일이나 스크립트로 Map / Reduce 작업을 만들고 실행할 수 있습니다.

    다른 예시:

    $HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar \
        -input myInputDirs \
        -output myOutputDir \
        -mapper /bin/cat \
        -reducer /bin/wc
    

    위의 예제에서 매퍼와 감속기는 모두 stdin에서 입력을 한 줄씩 읽은 다음 출력을 표준 출력으로 내보내는 실행 파일입니다. 이 유틸리티는 Map / Reduce 작업을 작성하고 해당 클러스터에 작업을 제출하며 완료 될 때까지 작업 진행을 모니터합니다.

    매퍼에 대해 실행 파일이 지정되면 매퍼가 초기화 될 때 각 매퍼 태스크가 별도의 프로세스로 실행 파일을 시작합니다. 매퍼 태스크가 실행되면 입력을 라인으로 변환하고 라인을 프로세스의 표준 입력으로 보냅니다. 그 동안 매퍼는 프로세스의 표준 출력에서 ​​라인 지향 출력을 수집하고 각 라인을 매퍼의 출력으로 수집 된 키 / 값 쌍으로 변환합니다. 기본적으로 첫 번째 탭 문자까지 줄의 접두사가 키이고 나머지 줄 (탭 문자 제외)이 값이됩니다. 행에 탭 문자가 없으면 전체 행이 키로 간주되고 값은 null입니다. 그러나 나중에 설명하는 것처럼 사용자 정의 할 수 있습니다.

    실행기가 감속기에 대해 지정되면 각 감속기 태스크는 실행 가능 파일을 별도의 프로세스로 실행 한 후 감속기를 초기화합니다. 감속기 태스크가 실행되면 입력 키 / 값 쌍을 행으로 변환하고 행을 프로세스의 표준 입력으로 보냅니다. 그 동안 감속기는 프로세스의 표준 출력으로부터 라인 지향 출력을 수집하고 각 라인을 감속기의 출력으로 수집되는 키 / 값 쌍으로 변환합니다. 기본적으로 첫 번째 탭 문자까지 줄의 접두사는 키이고 나머지 줄 (탭 문자 제외)은 값입니다. 그러나 이것은 사용자 정의 할 수 있습니다.

  3. from https://stackoverflow.com/questions/16345438/how-to-run-external-program-within-mapper-or-reducer-giving-hdfs-files-as-input by cc-by-sa and MIT license