
“여러 토픽에서 들어오는 데이터가 전부 도착해야 다음 작업을 실행해야 한다.”
이번에 구현하게된 기능 중 하나로 Redis를 이용한 분산 집계 구조 설계를 해보았다.
구현 중 발생한 오류를 해결하는 과정을 작성해보았다.
🚨 이 글을 쓰게 된 실제 문제 상황
우리는 하나의 작업을 수행하기 위해 서로 다른 4개의 Kafka 토픽에서 데이터를 받아야 했다.
| A | 5초 후 |
| B | 10초 후 |
| C | 15초 후 |
| D | 20초 후 |
즉, 마지막 토픽이 항상 제일 늦게 도착하는 구조였다.
처음에는 단순하게 이렇게 구현했다.
Kafka 메시지 수신 → Redis에 저장 → 현재까지 저장된 개수 확인 → 다 모이면 실행
그런데 운영 중 이상 현상이 발생했습니다.
- 마지막 토픽(위의 예시에서 D)에서 Kafka Lag 발생 : 마지막 토픽 메시지를 처리하는 Consumer가 멈춘 것처럼 보이는 현상 발생
- 후행 작업이 실행되지 않는 현상 : Redis에는 데이터가 모두 들어있는데도 다음 단계 작업이 실행되지 않는 경우 발생
🧨 원인 분석
처음에는 Redis로 집계하는 로직이 원인이라고 생각했지만 문제는 의외로 단순했다.
❌ Kafka Consumer 내부에서 집계를 시도했기 때문에
처음 구현한 Consumer 흐름 안에서 아래의 로직이 있었다.
메시지 수신 → Redis 조회 → 개수 부족 → return
문제는 이 로직이 4번째(마지막) 토픽 Consumer에서 계속 반복되었다는 점입니다.
| 데이터가 아직 덜 모임 | Consumer 계속 재시도 |
| Consumer가 Redis 반복 조회 | Poll 루프 지연 |
| Commit 지연 | Kafka Lag 증가 |
즉, 집계 로직이 Consumer를 붙잡고 있었던 것이다.
💡 해결 방향
Kafka Consumer의 역할은 단 하나다.
"메시지를 빠르게 읽어서 넘기는 것"
집계처럼 대기/조건확인/재시도가 들어가는 작업을 Kafka poll 스레드에서 수행하지 않도록 했다.
그래서 Kafka Poll 스레드에서는 최소 작업만 하고 별도의 스레드에 집계 작업을 위임하도록 변경했다.
Kafka → Reader → Worker → 다음 단계
| Reader | 메시지 수신 후 바로 전달 (절대 대기 안 함) |
| Worker | Redis 기반 집계 담당 |
| Redis | 데이터 저장 + 동기화 장치 |
Redis에 대해서는 추가적인 공부를 해야겠다.....!
🎯 Redis로 집계 로직 설계 시 추가한 점
Redis를 단순 저장소가 아니라 “집계 제어 장치” 로 사용했다.
3가지 Key를 활용합니다.
| DATA_KEY | 토픽별 데이터 임시 저장 |
| LOCK_KEY | 여러 Worker가 동시에 집계 못하게 막음 |
| DONE_KEY | 집계 완료 후 재실행 방지 |
Redis의 Key
✨ 이 구조를 도입하고 달라진 점
🔥 한 줄 결론
Kafka Consumer는 읽기 전용, 집계는 Worker에서 Redis 락 구조로 처리해야 안정적인 시스템이 된다.
'OpenSource > Kafka' 카테고리의 다른 글
| [Kafka] Zookeeper 기본 개념 정리 (0) | 2024.05.09 |
|---|---|
| [Kafka] 카프카 기본 용어 정리 (0) | 2024.05.08 |