
이 글은 하이브 완벽 가이드 책을 읽고 그 중 일부 내용을 정리한 글입니다.
하이브는 선언형 언어입니다. 사용자가 선언적 쿼리를 제출하면 하이브는 쿼리를 어떻게 맵리듀스 잡으로 변환할지 알아냅니다. 하이브의 성능을 최적화하기 위해서는 하이브가 어떻게 동작하는지 아는 과정이 필요합니다.
EXPLAIN 사용하기
하이브가 동작하는 방식을 알기 위해 가장 먼저 해볼 것은 EXPLAIN 기능을 사용하여 하이브가 쿼리를 어떻게 맵리듀스 잡으로 변환하는지를 살펴보는 것입니다. 쿼리 앞에 EXPLAIN 키워드를 넣으면 쿼리 계획과 추가 정보를 알 수 있습니다. EXPLAIN EXTENDED를 사용하면 좀 더 많은 정보를 확인할 수 있습니다.
LIMIT 튜닝
대부분 LIMIT 절은 여전히 데이터 전체에 대해 쿼리를 실행하고 일부 결과만을 반환합니다. hive.limit.optimize.enable을 true로 설정하면 hive.limit.row.max.size, hive.limit.optimize.limit.file이 동작 방식을 제어합니다. 전자는 LIMIT을 이용해 데이터의 작은 일부분만 처리할 때 처리를 보장하는 로우의 수를 의미하고 후자는 LIMIT을 이용해 데이터의 일부분만 처리할 때 샘플링할 수 있는 최대 파일 개수를 뜻합니다. 그런데 이 기능은 입력 데이터를 다 사용하지 않기 때문에 JOIN, GROUP BY와 같이 집계 함수를 사용할 때 실제와 상이한 결과를 도출할 수 있음을 유의해야 합니다.
로컬 모드
하이브의 입력 데이터 사이즈가 작을 경우에는 쿼리를 위해 태스크를 수행하는 부하가 전체 잡 수행 시간의 대부분을 차지합니다. 이때는 하이브가 제공하는 로컬 모드를 사용하면 단일 머신이나 동일 프로세스에서 잡의 모든 태스크를 수행할 수 있습니다. 로컬 모드 최적화를 적용하기 위해서는 hive.exec.mode.local.auto 속성을 true로 설정합니다.
병렬 수행
하이브는 쿼리를 하나 이상의 스테이지로 변환합니다. 스테이지는 맵리듀스 스테이지, 샘플링, 병합, 결과 개수 제한 등 하이브가 필요로 하는 모든 것이 될 수 있습니다. 하이브는 기본적으로 한 번에 한 스테이지만 실행합니다. 하지만 종속 관계가 없는 스테이지가 포함된 잡은 더 일찍 수행을 마칠 수 있게 병렬로 실행할 수 있습니다. 이를 위해서는 hive.exec.parallel 속성을 true로 설정하면 병렬 수행이 가능합니다. 그러나 잡이 병렬로 사용될 경우 클러스터 자원을 훨씬 많이 사용하니 주의해야 합니다.
strict 모드
하이브를 strict 모드로 설정하면 사용자가 의도하지 않거나 원하지 않는 효과를 발생시키는 쿼리 입력을 막아줍니다. hive.mapred.mode를 strict로 설정하면 다음 세 가지 종류의 쿼리를 쓰지 못합니다.
- 파티션이 있는 테이블에 WHERE 절에 범위를 제한하는 파티션 필터를 포함하지 않는 경우
- LIMIT 절 없이 ORDER BY 절을 사용하는 경우
- 카타시안 프로덕트
맵퍼와 리듀서 수의 최적화
하이브는 입력 크기에 따라 리듀서 개수를 정합니다. 리눅스의 du -s 명령어와 비슷한 dfs -count 명령으로 데이터의 크기를 계산할 수 있습니다. hive.exec.reducers.byte.per.reducer의 기본값은 1GB입니다. 이 값을 750MB로 바꾸면 하이브는 이 잡을 위해 네 개의 리듀서가 필요하다고 추정합니다.
하이브는 기본적으로 세 개의 리듀서를 산정합니다. mapred.reduce.tasks를 다양한 수를 설정하고 실험함으로써 최적의 리듀서 수를 산정할 수 있습니다. hive.exec.reducers.max 속성은 공유 클러스터에서 큰 잡을 다룰 때나 자원 사용률을 제어할 때 유용합니다. 이 속성을 통해 쿼리가 너무 많은 리듀서 자원을 사용하는 것을 막을 수 있습니다.
자바 가상 머신 재사용
자바 가상 머신의 재사용은 하이브 성능과 매우 밀접합니다. 특히 작은 파일을 처리해야 하는 겨웅와 대부분의 태스크가 수행 시간이 짧은 상황을 처리해야만 할 때 유용합니다.
하둡의 기본 설정은 일반적으로 포크된 JVM에서 맵 또는 리듀서 태스크를 실행합니다. JVM은 기동할 때 상당한 부하가 있습니다. 특히 수백 혹은 수천 번의 태스크를 가진 잡을 수행할 때 JVM 인스턴스의 재사용을 허용하면 동일한 잡에 N번 재사용됩니다. 이 값은 mapred.job.reuse.jvm.num.tasks 속성에서 설정할 수 있습니다. 이 기능은 재사용을 위해 필요하긴 하지만 JVM 재사용이 예약된 태스크 슬롯을 잡이 완료할 때까지 점유하고 있는 단점이 있습니다.
동적 파티셔닝 튜닝
hive.exec.max.dynamic.partitions 속성을 통해 동적 파티션의 수와 hive.exec.max.dynamic.partitions 속성을 통해 맵, 리듀스 노드에서 생성이 허용되는 최대 동적 파티션 수를 튜닝할 수 있습니다.
투기적 실행
투기적 실행은 중복된 태스크를 동시에 수행시키는 하둡의 기능입니다. 이 기능은 같은 데이터를 중복하여 복사하기 때문에 더 많은 리소스를 뜨고 대부분의 데이터는 버려집니다. 이 기능의 목적은 느리게 동작하는 태스크트래커를 제거함으로써 개별 태스크의 결과가 더 도출되고 결과적으로 전체 잡 수행을 향상시키는 데 있습니다. mapred.map.tasks.speculative.execution 속성을 true로 설정하면 동일한 맵 태스크를 실행하는 다수의 인스턴스가 동시에 실행되고 mapred.reduce.tasks.speculative.execution 속성을 true로 설정하면 동일한 리듀스 태스크를 실행하는 다수의 인스턴스가 동시에 실행됩니다.
다수의 GROUP BY 연산 결합하기
또 다른 최적화는 쿼리가 한 개의 맵리듀스 잡으로 변환되도록 다수의 GROUP BY 연산을 결합하는 것입니다. 이 최적화가 동작하려면 GROUP BY 키가 같아야 합니다. hive.mapred.multigroupby.singlemr 속성값은 단일 M/R 잡 계획을 만들어내는 다수의 group by 쿼리를 최적화할지 결정합니다.
가상 컬럼
하이브는 세 개의 가상 컬럼을 제공합니다. 하나는 스플릿의 입력 파일 이름이고, 나머지는 파일에 대한 블록 오프셋입니다. 이것은 하이브가 기대하지 않았던 값이나 null을 결과값으로 생성할 때 쿼리를 추적하기 위해 사용합니다. 세 번째 가상 컬럼은 파일의 로우 오프셋을 제공합니다. 이를 보기 위해서는 hive.exec.rowoffset 속성을 true로 설정해야합니다.
SET hive.exec.rowoffset=true;
SELECT INPUT_FILE_NAME, BLOCK_OFFSET_INSIDE_FILE, ROW_OFFSET_INSIDE_BLOCK
FROM hive_text WHERE line LIKE '%hive%' LIMIT 10;'Hadoop Ecosystem > Hive' 카테고리의 다른 글
| [하이브 완벽 가이드] Ch15. 하이브 파일과 레코드 포맷 사용자화 (0) | 2022.10.29 |
|---|---|
| [하이브 완벽 가이드] Ch11. 기타 파일 포맷과 압축 (0) | 2022.10.24 |
| [하이브 완벽 가이드] Ch9. 스키마 설계 (0) | 2022.10.06 |
| [하이브 완벽 가이드] Ch8. HiveQL : 색인(Index) (0) | 2022.10.04 |
| [하이브 완벽 가이드] Ch6. HiveQL : 쿼리 (0) | 2022.09.19 |