복붙노트

[HADOOP] Hadoop 프로세스 레코드는 블록 경계에서 어떻게 분리됩니까?

HADOOP

Hadoop 프로세스 레코드는 블록 경계에서 어떻게 분리됩니까?

Hadoop - The Definitive Guide에 따르면

레코드 라인이 두 개의 블록 (b1과 b2)으로 분할된다고 가정하십시오. 첫 번째 블록 (b1)을 처리하는 매퍼는 마지막 줄에 EOL 구분 기호가없고 다음 데이터 블록 (b2)의 나머지 줄을 가져 오는 것을 확인합니다.

두 번째 블록을 처리하는 매퍼 (b2)는 첫 번째 레코드가 불완전한 것으로 판단하여 블록 (b2)의 두 번째 레코드부터 처리해야합니까?

해결법

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

    1.흥미로운 질문으로, 세부 사항 코드를보고 몇 시간을 보냈으며 여기에 내 생각이 있습니다. 분할은 InputFormat.getSplits에 의해 클라이언트에 의해 처리되므로 FileInputFormat을 보면 다음과 같은 정보가 제공됩니다.

    흥미로운 질문으로, 세부 사항 코드를보고 몇 시간을 보냈으며 여기에 내 생각이 있습니다. 분할은 InputFormat.getSplits에 의해 클라이언트에 의해 처리되므로 FileInputFormat을 보면 다음과 같은 정보가 제공됩니다.

    그 후, TextInputFormat에 의해 정의 된 LineRecordReader를 보면, 그 행이 처리됩니다.

    따라서 스플릿은 클라이언트에서 계산되므로 매퍼는 순차적으로 실행할 필요가 없으며 모든 매퍼는 첫 번째 행을 무시할지 여부를 이미 알고 있습니다.

    그래서 기본적으로 동일한 파일에 각 100MB의 2 라인이 있고, 분할 크기가 64Mb라고 가정합시다. 그런 다음 입력 스플릿이 계산되면 다음과 같은 시나리오를 갖게됩니다.

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

    2.Map Reduce 알고리즘은 파일의 물리적 블록에서 작동하지 않습니다. 논리적 인 입력 분할에서 작동합니다. 입력 분할은 레코드가 작성된 위치에 따라 다릅니다. 레코드는 두 개의 Mappers에 걸쳐있을 수 있습니다.

    Map Reduce 알고리즘은 파일의 물리적 블록에서 작동하지 않습니다. 논리적 인 입력 분할에서 작동합니다. 입력 분할은 레코드가 작성된 위치에 따라 다릅니다. 레코드는 두 개의 Mappers에 걸쳐있을 수 있습니다.

    HDFS가 설정된 방식으로 대용량 파일을 큰 블록 (예 : 128MB 측정)으로 나누어 클러스터의 다른 노드에 이러한 블록의 세 복사본을 저장합니다.

    HDFS는 이러한 파일의 내용을 인식하지 못합니다. 레코드가 블록 -a에서 시작되었지만 해당 레코드의 끝이 블록 -b에있을 수 있습니다.

    이 문제를 해결하기 위해 Hadoop은 입력 스플릿이라고하는 파일 블록에 저장된 데이터의 논리적 표현을 사용합니다. MapReduce 작업 클라이언트는 입력 분할을 계산할 때 블록의 첫 번째 전체 레코드가 시작되는 위치와 블록의 마지막 레코드가 끝나는 위치를 파악합니다.

    요점 :

    블록의 마지막 레코드가 불완전한 경우 입력 분할에는 다음 블록의 위치 정보와 레코드를 완료하는 데 필요한 데이터의 바이트 오프셋이 포함됩니다.

    아래 다이어그램을보십시오.

    이 기사와 관련 SE 문제를 살펴보십시오. Hadoop / HDFS 파일 분할 정보

    자세한 내용은 설명서에서 읽을 수 있습니다.

    Map-Reduce 프레임 워크는 작업의 InputFormat을 사용하여 다음을 수행합니다.

    InputFormat를 확장 한 FileInputFormat은 getSplits () 메서드를 구현합니다. grepcode에서이 방법의 내부를 살펴보십시오.

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

    3.InputFormat은 데이터의 특성을 고려하여 논리적 인 분할로 데이터를 분할하는 역할을합니다. 작업에 상당한 대기 시간을 추가 할 수는 있지만 그렇게 할 수는 없습니다. 원하는 분할 크기 경계 주변의 모든 로직과 읽기가 작업 추적자에서 발생합니다. 가장 간단한 레코드 인식 입력 형식은 TextInputFormat입니다. 그것은 (코드에서 알 수있는 한) 다음과 같이 작동합니다. 입력 형식은 선에 관계없이 크기별로 분할을 작성하지만 LineRecordReader는 항상 다음과 같이 작동합니다. a) 첫 번째 분할이 아닌 경우 분할의 첫 번째 줄 건너 뛰기 (또는 그 중 일부) b) 끝 부분에서 분할의 경계 다음에 한 행을 읽습니다 (데이터가 사용 가능한 경우 마지막 분할이 아니므로).

    InputFormat은 데이터의 특성을 고려하여 논리적 인 분할로 데이터를 분할하는 역할을합니다. 작업에 상당한 대기 시간을 추가 할 수는 있지만 그렇게 할 수는 없습니다. 원하는 분할 크기 경계 주변의 모든 로직과 읽기가 작업 추적자에서 발생합니다. 가장 간단한 레코드 인식 입력 형식은 TextInputFormat입니다. 그것은 (코드에서 알 수있는 한) 다음과 같이 작동합니다. 입력 형식은 선에 관계없이 크기별로 분할을 작성하지만 LineRecordReader는 항상 다음과 같이 작동합니다. a) 첫 번째 분할이 아닌 경우 분할의 첫 번째 줄 건너 뛰기 (또는 그 중 일부) b) 끝 부분에서 분할의 경계 다음에 한 행을 읽습니다 (데이터가 사용 가능한 경우 마지막 분할이 아니므로).

  4. ==============================

    4.내가 이해 한 것으로부터 FileSplit이 첫 번째 블록에 대해 초기화 될 때 기본 생성자가 호출됩니다. 따라서 start 및 length 값은 처음에는 0입니다. 첫 번째 블록의 처리가 끝날 때 마지막 줄이 불완전하면 길이의 값이 분할의 길이보다 커지고 다음 블록의 첫 번째 줄도 읽게됩니다. 이 때문에 첫 번째 블록의 start 값은 0보다 크며이 조건에서 LineRecordReader는 두 번째 블록의 첫 번째 줄을 건너 뜁니다. (출처 참조)

    내가 이해 한 것으로부터 FileSplit이 첫 번째 블록에 대해 초기화 될 때 기본 생성자가 호출됩니다. 따라서 start 및 length 값은 처음에는 0입니다. 첫 번째 블록의 처리가 끝날 때 마지막 줄이 불완전하면 길이의 값이 분할의 길이보다 커지고 다음 블록의 첫 번째 줄도 읽게됩니다. 이 때문에 첫 번째 블록의 start 값은 0보다 크며이 조건에서 LineRecordReader는 두 번째 블록의 첫 번째 줄을 건너 뜁니다. (출처 참조)

    첫 번째 블록의 마지막 줄이 완료되면 길이 값은 첫 번째 블록의 길이와 같고 두 번째 블록의 시작 값은 0이됩니다. 이 경우, LineRecordReader는 최초의 라인을 스킵하지 않고, 최초의 2 번째의 블록을 읽어 들이지 않습니다.

    말이된다?

  5. ==============================

    5.hadoop의 LineRecordReader.java 소스 코드에서 생성자 : 몇 가지 주석을 찾았습니다.

    hadoop의 LineRecordReader.java 소스 코드에서 생성자 : 몇 가지 주석을 찾았습니다.

    // If this is not the first split, we always throw away first record
    // because we always (except the last split) read one extra line in
    // next() method.
    if (start != 0) {
      start += in.readLine(new Text(), 0, maxBytesToConsume(start));
    }
    this.pos = start;
    

    이것으로부터 나는 각 분할에 대해 하나의 추가 라인을 읽는다 (현재 분할의 끝에서 다음 분할에서 다음 라인을 읽음), 첫 번째 분할이 아니라면 첫 번째 라인이 버려 질 것이라고 생각한다. 라인 레코드가 손실되고 불완전 해지지 않도록

  6. ==============================

    6.매퍼는 의사 소통 할 필요가 없습니다. 파일 블록은 HDFS에 있으며 현재 매퍼 (RecordReader)는 나머지 줄이있는 블록을 읽을 수 있습니다. 이것은 뒤에서 발생합니다.

    매퍼는 의사 소통 할 필요가 없습니다. 파일 블록은 HDFS에 있으며 현재 매퍼 (RecordReader)는 나머지 줄이있는 블록을 읽을 수 있습니다. 이것은 뒤에서 발생합니다.

  7. from https://stackoverflow.com/questions/14291170/how-does-hadoop-process-records-split-across-block-boundaries by cc-by-sa and MIT license