1

ファイルを入力として受け取り、出力ファイルを提供する外部プログラムがあります

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

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

HDFS に入力ファイルと出力ファイルの両方が必要です

私は8つのノードを持つクラスターを持っています.そして、それぞれ1行の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 + ";");

file into file into local directory を取得せずに 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 ファイルの両方が必要です。

助けてください

4

2 に答える 2

0

したがって、外部プログラムが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 を取得し、hdfs に書き込む FSDataOutputStream を作成します。

基本的に、これら 2 つのものを含むプログラムは、HDFS を入力に変換し、出力を HDFS に戻すアダプターになります。

于 2013-05-02T23:48:41.370 に答える