토픽 분리 vs 파티션 분할
둘은 같은 말이 아니다.
- 토픽 분리: 토픽 자체를 여러 개로 나누는 것. 예:
rides.raw,rides.processed,rides.dlq - 파티션 분할: 하나의 토픽 내부를 파티션으로 나누는 것. 예:
Partition 0,1,2
목적도 다르다.
- 토픽 분리: 의미와 운영 정책을 분리한다.
- 파티션 분할: 처리량과 확장성을 확보한다.
토픽 자체를 분리하는 이유
- 도메인/스키마 분리: 이벤트 성격이 다르면 데이터 계약을 독립적으로 관리할 수 있다.
- 정책 분리: retention, ACL, 압축, 복제 정책을 토픽별로 다르게 설정할 수 있다.
- 운영 분리:
raw/processed/dlq단위로 모니터링하고 장애 대응하기 쉽다.
파티션으로 나누는 이유
- 병렬 처리: Consumer Group이 파티션을 나눠 읽어 처리량을 올린다.
- 수평 확장: 트래픽이 커지면 파티션/컨슈머 인스턴스를 함께 늘릴 수 있다.
- 순서 보장 범위 제어: 전체 토픽이 아니라 파티션 단위 순서를 보장한다.
- 복구 단순화: 오프셋을 파티션별로 관리해 재처리 범위를 줄일 수 있다.
DLQ(Dead Letter Queue) 패턴
DLQ는 “정상 처리에서 탈락한 이벤트를 격리하는 안전 구역”이다.
가장 흔한 흐름은 아래와 같다.
- Producer가 이벤트를
raw토픽에 적재한다. - Consumer/Flink가
raw를 읽어 검증하고 변환한다. - 성공 이벤트는
processed(또는 DB sink)로 보낸다. - 실패 이벤트는
dlq로 보내고 실패 메타데이터를 남긴다.
요점은 Producer가 분류를 다 하는 것이 아니라, 보통 처리 계층(Consumer/Flink)이 판정하고 분기한다는 점이다.
DLQ를 두면 좋은 점
- 본선 보호: 문제 이벤트가 있어도 정상 처리 흐름을 멈추지 않는다.
- 원인 추적: 실패 사유를 근거로 스키마 불일치나 버그를 빠르게 찾을 수 있다.
- 재처리 가능: 수정 후 DLQ 건만 선별해서 재주입할 수 있다.
운영 팁
DLQ 이벤트에는 최소한 아래 필드를 함께 남기는 것을 권장한다.
original_payload: 원본 메시지error_reason: 실패 사유 요약failed_at: 실패 시각source_topic: 원본 토픽명consumer_group: 실패를 기록한 처리 주체
선택적으로 stack_trace 또는 error_code를 넣으면 장애 분석 속도가 더 빨라진다.
한 줄 요약
- 토픽 분리는 의미와 정책을 나누기 위한 것
- 파티션 분할은 성능과 확장을 위한 것
- DLQ는 실패 데이터를 격리하고, 서비스 안정성과 운영 효율을 높이는 패턴