본문 바로가기

TIPS

Hive + Spark 실무 — 대용량 조인 성능 튜닝 실전 예제

728x90
반응형
SMALL

 

 

 

 

지난 포스팅에 이어서 실제 Hive + Spark 예제로 심화편을 단계적으로 풀어보려고 한다.

 

이번엔 실무에서 자주 쓰는 대용량 테이블 조인 최적화를 집중적으로 다뤄 보겠다

 

 

목표 시나리오

  • raw_event 테이블: 수십억 행의 로그 데이터
  • user_profile 테이블: 수백만 행의 유저 정보 (작음)

 

 

요구사항:

  • 최근 1개월 raw_event에서 특정 조건만 필터링 →
  • user_profile과 조인 →
  • 유저별 활동 집계 →
  • 결과 저장.

 

 

잘못된 접근 (느린 쿼리 예)
SELECT
  p.user_id,
  p.age_group,
  COUNT(e.event_id) AS event_count
FROM
  raw_event e
JOIN
  user_profile p
ON
  e.user_id = p.user_id
WHERE
  e.event_date >= '2025-06-01'
GROUP BY
  p.user_id, p.age_group;
 

문제점!

 

  • raw_event는 수십억 행인데, user_profile을 바로 조인한다.
  • Spark는 Shuffle Join 수행 → 대량 데이터 재분배 → 디스크 I/O + 네트워크 비용 ↑
  • 파티션 조건이 늦게 걸려서 Full Scan 발생.

 

 

성능 좋은 접근 — 단계별 Temp Table 활용

1. 먼저 필터링 + 집계 → Temp Table로 저장

CREATE TABLE temp_event_summary AS
SELECT
  user_id,
  COUNT(event_id) AS event_count
FROM
  raw_event
WHERE
  event_date >= '2025-06-01'
GROUP BY
  user_id;
 

여기서 이미 데이터량이 90% 이상 줄어든다!!

 

 

 

2. Temp Table과 작은 테이블 조인

SELECT
  p.user_id,
  p.age_group,
  t.event_count
FROM
  temp_event_summary t
JOIN
  user_profile p
ON
  t.user_id = p.user_id;
 

장점

  • 큰 테이블 → 작은 Temp Table로 변환 → 조인 비용 대폭 감소.
  • user_profile은 작은 테이블이라 Spark가 Broadcast Join 사용 가능 → Shuffle 방지.

 

 


 

Spark로 Broadcast Join 강제

 

Spark는 작은 테이블이면 자동으로 Broadcast Join을 시도한다.

그러나 크기를 못 추정하면 못할 수도 있으니, 명시적 힌트가 좋다.

 

SELECT /*+ BROADCAST(p) */
  p.user_id,
  p.age_group,
  t.event_count
FROM
  temp_event_summary t
JOIN
  user_profile p
ON
  t.user_id = p.user_id;
 

/*+ BROADCAST(테이블) */ → 작은 테이블을 Executor에 복제해서 Shuffle 없이 Local Join.

 


 

저장 포맷 최적화 — 컬럼형 + 압축
CREATE TABLE temp_event_summary
STORED AS PARQUET
AS
SELECT ...
 

 

  • Hive에서 TEXTFILE 대신 Parquet, ORC 사용 → 필요한 컬럼만 읽음.
  • Snappy 같은 경량 압축 적용 → 스캔 I/O 대폭 절감.

 

 


실행 계획 확인은 필수

 

Hive와 Spark SQL 모두 EXPLAIN 으로 플랜 확인해야 한다.

 

EXPLAIN
SELECT
  ...
 
  • 어떤 단계에서 Shuffle이 발생하는지
  • 어떤 쿼리 블록이 Full Scan인지
  • 파티션 Pruning이 정상 동작하는지

플랜 안 보면 결국 느린 이유 모름 상태 된다.

 

 


실전 꿀팁 요약!!
 
 
핵심 포인트
실전 대응
대용량 테이블
반드시 필터 → 집계 → Join
작은 테이블
Broadcast Join 강제
Shuffle 최소화
파티션 키 맞춰서 Join
저장 포맷
컬럼형 + Snappy
실행 계획
EXPLAIN 필수

 

 

 
+ 확장 아이디어
  • Dynamic Partition Pruning (DPP): Spark 3.0부터 지원. Join 전에 파티션 자동 줄이기.
  • Z-Order Clustering (Databricks): 필터 성능 극대화.
  • Materialized View: 정기 집계 결과 사전 생성.

 

 

 

 

 

 

학스의 개발일지

일상과 코딩 그 사이 어딘가에있는 블로그.. 블로거이자 빅데이터개발자 학스 입니다 JAVA, jQuery, PostgreSQL, MySQL, HIVE, Hadoop 더 많은 정보는 깃허브 주소 https://github.com/hacs2772 를 방문해주세요

hacs2772.tistory.com

 

728x90
반응형
LIST