Phase 7레슨 35
Dremel
Columnar Storage, Nested Data, Multi-level Execution — 페타바이트 분석 쿼리
💡ELI5·
엑셀과 컬럼 기반 저장
행 기반 (RDBMS): [id=1, name="kim", age=30, city="seoul", job="dev", ...] → "평균 나이" 쿼리 시 모든 컬럼을 읽어야 함 컬럼 기반 (Dremel): id: [1, 2, 3, ...] name: ["kim", "lee", "park", ...] age: [30, 25, 40, ...] ← 이것만 읽으면 됨! city: ["seoul", "busan", ...] → "평균 나이" 쿼리 시 age 컬럼만 읽음 (I/O 1/N)
💡 비유 — 엑셀에서 '평균 나이'를 구할 때, 이름/도시/직업 열까지 읽을 필요 없이 나이 열만 보면 된다. 컬럼 기반 저장은 이 '필요한 열만 디스크에서 읽기'를 극대화. 100개 열 중 1개만 조회하면 99% I/O 절약.
🔬Deep Dive·
행 기반 vs 컬럼 기반
| 구분 | 행 기반 (RDBMS) | 컬럼 기반 (Dremel/BigQuery) |
|---|---|---|
| 저장 | 행 단위 (한 행의 모든 컬럼이 인접) | 컬럼 단위 (같은 컬럼끼리 인접) |
| 조회 | 모든 컬럼 읽음 | 필요 컬럼만 읽음 |
| 압축 | 낮음 (행마다 다양한 타입) | 높음 (같은 타입 연속) |
| 쓰기 | 빠름 (한 번에 한 행) | 느림 (여러 컬럼 파일 갱신) |
| 적합 | 트랜잭션 (OLTP) | 분석 (OLAP) |
🔬Deep Dive·
Multi-level Execution
쿼리: SELECT city, AVG(age) FROM users GROUP BY city
[Root Server] (1)
|
┌─────────┼─────────┐
[Mid-1] [Mid-2] [Mid-3] (수십)
| | |
[Leaf] [Leaf] [Leaf] (수천)
| | |
[데이터] [데이터] [데이터]
Leaf: 로컬 데이터 읽어 city별 부분 집계
Mid: 여러 Leaf의 부분 집계를 병합
Root: 최종 결과 조합 → 클라이언트🔬Deep Dive·
Dremel → BigQuery
| 구분 | Dremel (내부) | BigQuery (상용) |
|---|---|---|
| 사용자 | Google 내부 | 모든 사용자 |
| 인프라 | 사용자가 관리 | 서버리스 (Google 관리) |
| SQL | 내부 쿼리 언어 | 표준 SQL |
| 스케일링 | 수동 | 자동 |
| 과금 | 내부 | 쿼리 스캔 바이트 기반 |
⚖️Trade-off·
컬럼 기반의 Trade-off
| 이점 | 대가 |
|---|---|
| 분석 쿼리 빠름 (컬럼만 읽음) | 단일 행 조회/쓰기 느림 |
| 높은 압축률 (같은 타입 연속) | 트랜잭션에 부적합 (OLAP 전용) |
| 페타바이트 스케일 분석 | 중첩 데이터 인코딩 복잡 |
| 인터랙티브 쿼리 (수 초) | 실시간 쓰기 제한 (스트리밍 삽입 별도) |
❓ 체크포인트 질문
- 1.컬럼 기반 저장이 분석 쿼리에 빠른 이유는?
- 2.Dremel이 MapReduce와 다른 점은?
- 3.중첩 데이터(Protocol Buffers)를 컬럼으로 분해하는 것이 왜 어려운가?
- 4.Multi-level Execution이란?
- 5.BigQuery가 Dremel을 상용화하면서 추가한 것은?