복붙노트

[HADOOP] Hadoop Mapreduce 프로그램의 출력을 프로그래밍 방식으로 읽음

HADOOP

Hadoop Mapreduce 프로그램의 출력을 프로그래밍 방식으로 읽음

이것은 기본적인 질문 일지 모르지만 Google에서 답변을 찾을 수 없습니다. 출력 디렉토리에 여러 개의 출력 파일을 만드는 map-reduce 작업이 있습니다. 내 Java 애플리케이션은 원격 hadoop 클러스터에서이 작업을 실행하고 작업이 완료된 후 org.apache.hadoop.fs.FileSystem API를 사용하여 프로그램 적으로 출력을 읽어야한다. 가능한가? 응용 프로그램은 출력 디렉토리를 알고 있지만 map-reduce 작업에 의해 생성 된 출력 파일의 이름은 알지 못합니다. hadoop 파일 시스템 API에서 디렉토리의 내용을 프로그램 방식으로 나열 할 수있는 방법이없는 것 같습니다. 출력 파일은 어떻게 읽습니까? 그런 평범한 시나리오 인 것 같습니다. 해결책이 있다고 확신합니다. 그러나 나는 아주 명백한 것을 놓치고있다.

해결법

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

    1.찾고있는 메소드를 listStatus (Path)라고합니다. Path 내부의 모든 파일을 FileStatus 배열로 반환하기 만하면됩니다. 그런 다음 경로 객체를 반복하고 읽을 수 있습니다.

    찾고있는 메소드를 listStatus (Path)라고합니다. Path 내부의 모든 파일을 FileStatus 배열로 반환하기 만하면됩니다. 그런 다음 경로 객체를 반복하고 읽을 수 있습니다.

        FileStatus[] fss = fs.listStatus(new Path("/"));
        for (FileStatus status : fss) {
            Path path = status.getPath();
            SequenceFile.Reader reader = new SequenceFile.Reader(fs, path, conf);
            IntWritable key = new IntWritable();
            IntWritable value = new IntWritable();
            while (reader.next(key, value)) {
                System.out.println(key.get() + " | " + value.get());
            }
            reader.close();
        }
    

    Hadoop 2.x의 경우 다음과 같이 독자를 설정할 수 있습니다.

     SequenceFile.Reader reader = 
               new SequenceFile.Reader(conf, SequenceFile.Reader.file(path))
    
  2. ==============================

    2.몇 가지 옵션이 있습니다. 여기에 두 가지가 있습니다.

    몇 가지 옵션이 있습니다. 여기에 두 가지가 있습니다.

    방법 # 1 : 데이터 크기에 따라 다음 HDFS 명령을 사용하는 것입니다 (항목 6 참조).

    hadoop fs -getmerge hdfs-output-dir local-file
    // example 
    hadoop fs -getmerge /user/kenny/mrjob/ /tmp/mrjob_output
    // another way
    hadoop fs -cat /user/kenny/mrjob/part-r-* > /tmp/mrjob_output
    

    "이것은 HDFS 파일 인 hdfs-output-dir / part- *를 하나의 로컬 파일에 연결합니다."

    그런 다음 하나의 파일을 읽을 수 있습니다. (HDFS가 아닌 로컬 저장소에 있음)

    방법 # 2 : 도우미 메서드 만들기 : (나는 Configuration, FileSystem 인스턴스 및 다른 도우미 메서드가 포함 된 HDFS라는 클래스가 있습니다.)

    public List<Path> matchFiles(String path, final String filter) {
            List<Path> matches = new LinkedList<Path>();
            try {
                FileStatus[] statuses = fileSystem.listStatus(new Path(path), new PathFilter() {
                           public boolean accept(Path path) {
                              return path.toString().contains(filter);
                           }
                        });  
                for(FileStatus status : statuses) {
                    matches.add(status.getPath());
                }
            } catch(IOException e) {
            LOGGER.error(e.getMessage(), e);
            }
            return matches;
        }
    

    그러면 다음과 같은 명령을 통해 호출 할 수 있습니다. hdfs.matchFiles ( "/ user / kenny / mrjob /", "part-")

  3. ==============================

    3.

                FSDataInputStream inputStream = fs.open(path);
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String record;
                while((record = reader.readLine()) != null) {
                    int blankPos = record.indexOf(" ");
                    System.out.println(record+"blankPos"+blankPos);
                    String keyString = record.substring(0, blankPos);
                    String valueString = record.substring(blankPos + 1);
                    System.out.println(keyString + " | " + valueString);
                }
    
  4. from https://stackoverflow.com/questions/5634137/programmatically-reading-the-output-of-hadoop-mapreduce-program by cc-by-sa and MIT license