728x90
반응형
SMALL

빅데이터를 다루다 보면 다양한 문제에 마주치는 경우가 있다
그중 다양한 문제들이 있는데 오늘은 그것에 대해 다룰 예정이다
(조금 어렵긴 하다)
1. 쿼리 병목 — 느린 쿼리가 전체 흐름 잡아먹는다
- 빅데이터 처리에서 DB나 DW 쿼리가 가장 큰 병목이다.
- JOIN 남발, 서브쿼리 중첩, INDEX 미적용, 불필요한 Full Scan 등 원인이 다양하다.
핵심 대응
↓↓↓
- Partitioning, Bucketing: 데이터 분할 저장으로 병렬 처리 최적화.
- Temp Table: 복잡한 쿼리를 여러 단계로 쪼개고 중간 결과를 임시 테이블로 저장해 중복 스캔 방지.
- Materialized View: 자주 쓰는 집계 결과를 미리 만들어둠.
- Index: Hive나 Elasticsearch 등에서도 인덱싱 전략 설계 중요.
2. 디스크 I/O — 느린 읽기/쓰기
- 데이터가 너무 크면 디스크 I/O가 병목이다.
- 특히 HDFS, S3, Hive 등에서 대용량 데이터를 자주 스캔하면 속도가 급격히 느려진다.
핵심 대응
↓↓↓
- 컬럼형 저장 포맷 사용 (Parquet, ORC): 필요한 컬럼만 읽음 → 스캔 비용 대폭 절감.
- 압축 알고리즘 선택 (Snappy, ZSTD): I/O 줄이고, 압축/해제 비용 최적화.
- 데이터 파티셔닝 구조 설계: 날짜, 지역, 키 값으로 파티션.
3. Shuffle — Spark나 Hive의 숨은 병목
- Spark 같은 분산 처리 프레임워크에서 가장 무거운 연산은 Shuffle이다.
- Shuffle은 데이터를 네트워크로 재분배하므로 디스크 I/O + 네트워크 비용이 중첩된다.
핵심 대응
↓↓↓
- broadcast join 활용: 작은 테이블은 전체 Executor에 복제해서 Shuffle 방지.
- 파티션 키 설계: Shuffle 최소화.
- map-side join 고려.
- 중간 출력 최소화: Narrow Transformations 위주로 설계.
4. 메모리 부족 — OutOfMemory
- Spark Executor 메모리가 부족하면 디스크 spill, GC 병목, 심하면 OOM 발생.
- 파티션 너무 크거나 DataFrame 캐싱 설계가 잘못되면 자주 발생.
핵심 대응
↓↓↓
- 적절한 파티션 크기 (Partition Size): 일반적으로 128MB ~ 512MB 권장.
- 불필요한 cache() 남발 금지. 필요할 때만 persist.
- GC 튜닝. (메모리 사용량 모니터링 필수)
5. 네트워크 병목
- 클러스터 간 대용량 데이터 전송이 많으면 네트워크가 병목.
- 특히 Shuffle, Join 단계에서 심각.
핵심 대응
↓↓↓
- 데이터 로컬성(data locality) 극대화: 데이터가 있는 노드에서 연산 수행.
- 스케줄러 설정 조정: 같은 Rack에 Job 할당.
- 대용량 결과는 필요 시 압축해서 전송.
그렇다면 예시로 풀어보자
Hive 쿼리 튜닝에서 Temp Table 활용
Temp Table은 특히 Hive, Presto 같은 MPP 기반 쿼리에서 유용하다.
예:
-- 1단계: 큰 Join 전에 Filter + Group By 결과를 임시 테이블에 저장
CREATE TABLE temp_filtered AS
SELECT user_id, COUNT(*) AS cnt
FROM raw_table
WHERE date >= '2025-01-01'
GROUP BY user_id;
-- 2단계: Join은 작은 Temp Table과만 수행
SELECT *
FROM temp_filtered t
JOIN user_profile u ON t.user_id = u.user_id;
이렇게 하면:
- 원본 테이블을 여러 번 Scan하지 않음.
- 중간 결과는 작은 사이즈라서 Join 성능 극대화.
- 특히 반복 실행 시 Temp Table만 새로 갱신하면 됨.
요약
|
문제
|
주요 원인
|
대응
|
|
느린 쿼리
|
복잡한 조인/서브쿼리
|
파티셔닝, Temp Table, View
|
|
디스크 I/O
|
대량 Full Scan
|
컬럼형 저장, 압축, 파티션
|
|
Shuffle
|
분산 재분배
|
Broadcast Join, 키 설계
|
|
메모리 부족
|
Executor 메모리 초과
|
파티션 최적화, 캐싱 설계
|
|
네트워크 병목
|
노드 간 대량 전송
|
로컬 처리, 스케줄링
|
이렇게 빅데이터에 이상 문제의 종류와 대응방법에 대해 다뤄 보았다
아무래도 실무에서 자주일어나는 문제에 대해 다뤘다보니
다른 중요한 문제들이 빠진게 있긴한데
그런것들은 다음 포스팅에 하나씩 추가할 예정이다.
학스의 개발일지
일상과 코딩 그 사이 어딘가에있는 블로그.. 블로거이자 빅데이터개발자 학스 입니다 JAVA, jQuery, PostgreSQL, MySQL, HIVE, Hadoop 더 많은 정보는 깃허브 주소 https://github.com/hacs2772 를 방문해주세요
hacs2772.tistory.com
728x90
반응형
LIST
'TIPS' 카테고리의 다른 글
| Spark 실전 성능 튜닝 #Executor, #Shuffle, #GC (4) | 2025.07.21 |
|---|---|
| Hive + Spark 실무 — 대용량 조인 성능 튜닝 실전 예제 (4) | 2025.07.14 |
| #ConcurrentHashMap 안전한 멀티스레드 Map의 모든 것 (1) | 2025.06.30 |
| Java Memory Model (JMM)과 volatile 키워드 — 동시성 프로그래밍의 핵심 (2) | 2025.06.23 |
| CompletableFuture — 자바의 현대적 비동기 프로그래밍 (1) | 2025.06.16 |