복붙노트

[HADOOP] 하둡 FileSplit 읽기

HADOOP

하둡 FileSplit 읽기

해당 파일에서 실제 바이트를 읽기 위해 FileSplit 오브젝트를 사용하는 클라이언트 애플리케이션을 가정하십시오.

이렇게하려면 FileSplit에서 다음과 같은 코드를 통해 InputStream 객체를 만들어야합니다.

    FileSplit split = ... // The FileSplit reference
    FileSystem fs   = ... // The HDFS reference

    FSDataInputStream fsin = fs.open(split.getPath());

    long start = split.getStart()-1; // Byte before the first

    if (start >= 0)
    {
        fsin.seek(start);
    }

스트림을 -1로 조정하는 것은 Hadoop MapReduce LineRecordReader 클래스와 같은 일부 시나리오에 있습니다. 그러나 FSDataInputStream seek () 메소드의 문서에 따르면 위치를 찾은 후 다음 위치에서 해당 위치를 읽게되므로 위의 코드가 1 바이트 (?)라는 의미입니다 (?).

그렇다면 모든 InputSplit 리딩 케이스에 "-1"조정이 필요한가?

그건 그렇고, FileSplit을 올바르게 읽으려면 시작을 찾는 것만으로는 충분하지 않습니다. 모든 분할에는 실제 HDFS 파일의 끝과 동일하지 않을 수도 있기 때문입니다. 따라서 해당 InputStream은 "바운드"되어야합니다. 즉, 다음과 같이 최대 길이를 가져야합니다.

    InputStream is = new BoundedInputStream(fsin, split.getLength());

이 경우, "네이티브"fsin 스팀이 생성 된 후에는 "bounding"을 구현하기 위해 org.apache.commons.io.input.BoundedInputStream 클래스가 사용됩니다.

최신 정보

명백하게 조정은 LineRecordReader 클래스 중 하나 인 lineRecords 클래스 중 하나의 경우에만 마지막 행 전체를 읽도록 분할 경계를 초과하는 경우에만 조정이 필요합니다.

이에 대한 자세한 내용은 이전 질문과 MAPREDUCE-772에 대한 주석에서 확인할 수 있습니다.

해결법

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

    1.위치 0을 찾으면 InputStream.read ()에 대한 다음 호출에서 바이트 0을 읽습니다. 위치 -1을 찾으면 예외가 발생합니다.

    위치 0을 찾으면 InputStream.read ()에 대한 다음 호출에서 바이트 0을 읽습니다. 위치 -1을 찾으면 예외가 발생합니다.

    예제와 소스 코드에서 표준 패턴에 대해 이야기 할 때 구체적으로 언급하고있는 곳

    참고로 분할은 불필요하게 묶이지 않습니다. 예를 들어 TextInputFormat과 분할 가능한 파일을 사용하십시오. 분할을 처리하는 레코드 리더는 다음을 수행합니다.

    이것은 발견 된 다음 줄 바꾸기가 분할의 끝을 지났거나 EOF가 발견 될 때까지 반복됩니다. 따라서이 경우 분할의 실제 경계가 입력 분할에 의해 주어진 경계에서 오른쪽으로 이동할 수 있음을 알 수 있습니다

    최신 정보

    LineRecordReader에서이 코드 블록을 참조하십시오.

    if (codec != null) {
      in = new LineReader(codec.createInputStream(fileIn), job);
      end = Long.MAX_VALUE;
    } else {
      if (start != 0) {
        skipFirstLine = true;
        --start;
        fileIn.seek(start);
      }
      in = new LineReader(fileIn, job);
    }
    if (skipFirstLine) {  // skip first line and re-establish "start".
      start += in.readLine(new Text(), 0,
                           (int)Math.min((long)Integer.MAX_VALUE, end - start));
    }
    

    --start 문은 개행 문자에서 시작하여 빈 레코드를 첫 번째 레코드로 반환하지 않도록 처리하는 것이 가장 좋습니다. 탐색이 발생하면 첫 번째 줄을 건너 뛰어 파일 분할이 겹치는 레코드를 반환하지 않도록합니다.

  2. from https://stackoverflow.com/questions/16180130/hadoop-filesplit-reading by cc-by-sa and MIT license