💡 이 문서는: Flink에서 여러 연산자를 하나의 태스크로 묶어 실행하는 Operator Chaining 최적화 기법을 다룹니다. Flink에선 기본적으로 큰 작업이나 IO 관련된 부분에서 체인을 끊는 방식으로 제공하고 있고 최적화가 잘 되어 있어 공식문서나 커뮤니티에서도 기본 설정으로 사용하는 것을 추천하지만, 알면 내 마음대로 할 수 있고 모르면 Flink 맘대로 하는 것이기 때문에 조사한 내용을 정리한다.
Operator Chaining은 여러 연산자를 하나의 태스크로 묶어 실행하는 최적화 기법입니다.
체이닝 전
┌────────┐ ┌─────────┐ ┌─────────┐ ┌──────┐
│ Source │ → │ Filter1 │ → │ Filter2 │ → │ Map │
└────────┘ └─────────┘ └─────────┘ └──────┘
↓ ↓ ↓ ↓
4개의 독립 태스크, 3번의 네트워크 전송
체이닝 후
┌──────────────────────────────────────┐
│ Source → Filter1 → Filter2 → Map │
└──────────────────────────────────────┘
↓
1개의 태스크, 0번의 네트워크 전송
| 항목 | 설명 | 효과 |
|---|---|---|
| 메모리 참조 전달 | 객체를 직렬화하지 않고 포인터만 전달 | 직렬화 비용 제거 |
| 단일 스레드 실행 | 같은 스레드에서 연속 실행 | Context Switch 제거 |
| L1 Cache 활용 | 같은 CPU 코어에서 실행 | Cache Hit Rate 95%+ |
연산자가 체이닝되려면 모든 조건을 만족해야 합니다:
| 조건 | 설명 | 확인 방법 |
|---|---|---|
| ✅ 같은 병렬도 | setParallelism()이 동일 |
Flink Web UI → Job Graph |
| ✅ 같은 슬롯 그룹 | slotSharingGroup()이 동일 |
코드 검토 |
| ✅ 체이닝 활성화 | disableChaining() 미호출 |
코드 검토 |
| ✅ 재분배 없음 | keyBy(), rebalance() 등 없음 |
데이터 흐름 분석 |
| ✅ Forward 전략 | 1:1 데이터 전달 | 파티션 전략 확인 |
source.setParallelism(4) .filter(...).setParallelism(2) // 체이닝 불가
source.filter(...) .keyBy(...) // 체이닝 경계 (재분배 발생)