Hive SQL 을 사용하여 동적 파티션에 대한 Parquet 테이블 OOM 예외 분석 삽입
1. 예외 설명
"INSERT ... SELECT" 문을 실행하여 Parquet 또는 ORC 형식의 테이블에 데이터를 삽입할 때 동적 파티션이 활성화된 경우 다음 오류가 발생하여 작업이 제대로 실행되지 않을 수 있습니다.
Hive 클라이언트:
(좌우로 미끄러질 수 있음)
YARN 의 888 에서 특정 map task 보고 오류 보고:
(좌우로 미끄러질 수 있음)
2. 예외 분석
parq8 이러한 형식을 사용하려면 파일에 쓰기 전에 배치의 행 (batches of rows) 을 메모리에 캐시해야 합니다. INSERT 문을 실행할 때 동적 파티션은 현재 동적 파티션 디렉토리당 하나 이상의 파일 작성기 (file writer) 를 여는 것으로 구현되고 있습니다. 이러한 버퍼는 파티션별로 유지 관리되므로 런타임 시 필요한 메모리 양은 파티션 수가 증가함에 따라 증가합니다. 따라서 열려 있는 파일 작성기 (file writer) 수에 따라 mappers 또는 reducers 의 OOM 이 발생하는 경우가 많습니다.
INSERT 문을 통해 동적 파티션 테이블에 데이터를 삽입하거나 HDFS 에서 동시에 열 수 있는 파일 수 제한을 초과할 수 있습니다.
join 또는 합산이 없으면 INSERT ... SELECT 문은 map 작업만 있는 작업으로 변환됩니다. Mapper 작업은 입력 레코드를 읽고 대상 파티션 디렉토리로 전송합니다. 이 경우 각 mapper 는 발견된 각 동적 파티션에 대해 새로운 파일 작성기 (file writer) 를 만들어야 합니다. Mapper 가 런타임 시 필요한 메모리 양은 발생하는 파티션 수가 증가함에 따라 증가합니다.
3. 예외 재현 및 해결
3.1. 동적 파티션 생성을 위한 몇 가지 매개 변수 설명
hive.exec.dynamic.partition
기본값: false
동적 파티션을 사용하는 경우 이 매개 변수를 true 로 설정해야 합니다.
hive.exec.dynamic.partition.mode
기본값: strict
동적 파티션의 모드, 기본 strict 는 하나 이상의 파티션을 정적 파티션으로 지정해야 함을 의미합니다
일반적으로 nonstrict
hive.exec.max.dynamic.partitions.pernode
기본값 1
으로 설정해야 합니다
이 매개변수는 실제 데이터를 기준으로 설정해야 합니다. < P > 예: 소스 데이터에 1 년 데이터가 포함되어 있습니다. 즉, day 필드에 365 개 값이 있는 경우 이 매개변수를 365 보다 크게 설정해야 하며 기본값 1 을 사용하면 오류가 보고됩니다.
hive.exec.max.dynamic.partitions
기본값: 1
MR 을 실행하는 모든 노드에서 최대 * * * 생성할 수 있는 동적 파티션 수.
위와 같은 매개 변수 설명.
hive.exec.max.created.files
기본값: 1
전체 Mr 작업에서 작성할 수 있는 최대 HDFS 파일 수. < P > 일반 기본값은 데이터 양이 너무 커서 생성해야 하는 파일 수가 1 보다 크면 실제 상황에 맞게 조정할 수 있습니다.
mapreduce.map.memory.mb
map 작업에 대한 물리적 메모리 할당 값 (일반적으로 1GB,2GB,4GB 등으로 설정됨).
mapreduce.map.Java.opts
map 작업에 대한 Java 스택 크기 설정은 일반적으로 위 값의 75% 미만으로 설정되어 map 작업에 충분한 스택 외 메모리 공간이 있도록 합니다.
mapreduce.input.fileinputformat.split.maxsize
mapreduce.input.fileinputformat.ssize 예를 들어, 저는 173741824 로 설정했습니다. 각 맵이 1GB 파일을 처리할 수 있도록 하기 위해서입니다.
3.2. 예를 들어
Fayson 은 지난 이틀 동안 Hive SQL 을 사용하여 동적 파티션을 삽입하는 Parquet 테이블을 조정할 때 항상 잘못된 OOM 을 보고하는 것도 오랜 시간이 걸렸습니다. 전체 과정을 살펴 보겠습니다.
1. 먼저 실행 스크립트의 내용을 살펴보겠습니다. 기본적으로 Hive 의 insert 문을 사용하여 텍스트 데이터 테이블을 다른 parquet 테이블에 삽입하는 것입니다. 물론 동적 파티션을 사용합니다.
2. 원본 데이터 파일, 텍스트 파일, 하나 *** 12 개, 각각 3GB 크기, 총 * * * 약 3.6TB 를 살펴 보겠습니다.
3. 오류 보고
4. 단 하나의 m 이기 때문이다 Ap 의 MapReduce 작업, YARN 의 888 에서 이 작업을 관찰할 때, 기본적으로 어떤 map 도 성공할 수 없고, 모두 실패한다는 것을 알 수 있다. (윌리엄 셰익스피어, Northern Exposure (미국 TV 드라마), 성공명언) 위의 잘못을 보고하다.
5. mapreduce.map.memory.mb 를 2GB 에서 4GB, 8GB, 16GB 로 증가, 해당 mapreduce.map.java.opts 를 3GB 로 증가 여전히 잘못된 OOM 을 보고하다.
6. 이후 mapreduce.input.fileinputformat.split.maxsize 를 1GB 에서 512MB, 256MB 로 줄여 맵 수를 늘리고 개별 map 을 줄였다 여전히 잘못된 OOM 을 보고하다.
7. 마지막으로 hive.optimize.sort.dynamic.partition 을 활성화하고 reduce 프로시저를 추가하면 작업이 성공적으로 실행됩니다.
8. 마지막으로 결과 파일을 보면 입력 파일의 약 3 분의 1 인 약 1.2TB 가 됩니다. 1 *** 1557 개의 파티션, 최대 파티션 파일은 2GB 입니다.
4. 예외 요약
이 예외의 경우 다음과 같은 세 가지 방법으로 처리하는 것이 좋습니다.
1. hive.optimize.sort.dynamic.partition 을 활성화하고 로 설정합니다 이 최적화를 통해 맵 작업만 있는 이 MapReduce 는 reduce 프로세스를 도입하여 동적 파티션의 필드 (예: 날짜가 reducer 로 전달될 때 정렬됨) 를 도입합니다. 파티션 필드는 정렬되기 때문에 각 reducer 는 항상 하나의 파일 작성기 (file writer) 만 열어 두고 특정 파티션에서 모든 행을 받은 후 레코드 작성기 (record writer) 를 꺼서 메모리 압력을 줄이기만 하면 됩니다. 이 최적화 방법은 parquet 파일을 쓸 때 비교적 적은 메모리를 사용하지만 파티션 필드를 정렬하는 데 비용이 듭니다.
2. 두 번째 방법은 각 mapper 의 메모리 할당을 늘리는 것입니다. 즉, mapreduce.map.memory.mb 와 mapreduce.map.java.opts 를 늘려 모든 파일 기록기 (FIP
3. 조회를 여러 개의 작은 조회로 분할하여 조회당 작성되는 분할 수를 줄입니다. 이렇게 하면 각 mapper 가 더 적은 수의 파일 작성기 (file writer) 를 열 수 있습니다.
참고:
기본적으로 Hive 는 열려 있는 각 Parquet 파일 버퍼 (file buffer) 에 128MB 를 할당합니다. 이 버퍼 크기는 매개변수 parquet.block.size 에 의해 제어됩니다. 최적의 성능을 위해, parquet 의 buffer size 는 HDFS 의 block size 와 정렬 (예: 같음) 해야 각 parquet 파일이 단일 HDFS 블록 내에 있으므로 각 입출력 요청이 네트워크 전송을 통해 후속 block 에 액세스할 필요 없이 전체 데이터 파일을 읽을 수 있습니다.
참조:
/blog/214/3/how-to-use-parquet-with-impala-hive-pig-mark