Apache Flink + RocksDB 튜닝으로 광고 Frequency Capping 실시간 집계를 일주일까지 확장하기
이승민/최원용 · 토스 · 토스 기술 블로그
소개
1분부터 7일까지 슬라이딩 윈도우 Frequency Capping을 세 Flink 앱으로 분리하고 각각의 병목을 해결한 기록을 공유합니다.
AI 핵심 요약
기존 Airflow 배치 구조는 장기 슬라이딩 집계를 시간 단위로 절삭하고 서빙 때 여러 Redis 계층을 합산해야 해, 1분부터 7일까지의 정밀한 실시간 집계를 제공하기 어려웠습니다. 이를 해결하기 위해 집계 구간별 병목이 다르다는 점을 고려해 Flink 앱을 minutes·hours·days로 분리하고, State를 단일 진실 공급원으로 삼아 Redis를 재구성할 수 있도록 설계했습니다. 특히 days 앱은 만료 타이머가 없는 백필과 타이머를 등록하는 캐치업을 별도 파이프라인으로 나누고, eventTime 기준 Redis 쓰기와 timerState TTL 등으로 전환 정합성을 확보했습니다. 운영 중에는 앱별 지표와 프로파일링을 바탕으로 RocksDB 메모리·레벨·Filter Block 설정, Flink 메모리와 직렬화를 조정했으며, 병목은 앱마다 다르므로 설정을 분리하고 실제 동작을 측정해 튜닝해야 한다는 점을 보여줍니다.
- 백필은 카운트만 쌓고 캐치업은 만료 타이머까지 재구축하므로, 두 단계를 분리하고 별도 Kafka Consumer Group을 사용해야 합니다.
- Watermark가 느린 파티션에 막힐 수 있으므로 Redis 쓰기 여부는 전체 watermark가 아니라 이벤트의 eventTime으로 판단합니다.
- RocksDB의 Write Stall은 write_buffer_size만 키우기보다 managed memory와 WBR을 조정해 Write Buffer Manager의 실제 예산을 확보해야 합니다.
- Direct I/O에서는 Filter Block Cache Miss가 디스크 읽기로 이어지므로, 대형 SST를 다룰 때 partitioned-index-filters 설정을 검토해야 합니다.
- 설정값은 Flink 내부에서 덮어써질 수 있으므로, 실제 적용 여부를 소스 코드와 운영 지표로 확인해야 합니다.
비슷한 학습 자료
Iceberg Low-Latency Queries with Materialized Views (feat. 실시간 거래 리포트)
엔지니어링데이 2025 · YouTube
Paimon 겟또다제 ! (w/ ADVoost Shopping)
엔지니어링데이 2025 · YouTube
고객은 절대 기다려주지 않는다: 빠른 데이터 서빙으로 고객 만족도를 수직 상승 시키는 법
이세찬 · 토스 기술 블로그
Spark Job 성능 모니터링과 최적화를 위한 Spark Analyzer 개발기
김문수 · 토스 기술 블로그
Kafka Streams 윈도우 도입기
박지환 · 컬리 기술 블로그
Dataflow로 컬리의 준실시간 수요 예측모델 파이프라인 구축하기 - 1편
한수진 · 컬리 기술 블로그