하루 1,500억 이벤트를 견딘 StreamHub, Kafka 전환 뒤 드러난 병목

Atlassian의 이벤트 스트리밍 플랫폼 StreamHub는 하루 220억 건을 처리하던 시스템에서 하루 1,500억 건을 수집하는 플랫폼으로 커졌어요. Kinesis가 안정적으로 맡아 온 구간을 넘어선 뒤에는 AWS MSK 기반 Kafka와 계층형 저장소를 선택했어요. 전환 뒤에도 브로커 네트워크, S3 요청, 관리형 서비스의 제어 영역이 새 병목으로 나타났어요. 1
핵심 요약
| 구분 | 핵심 | 왜 볼 만한가요 |
| 처리 규모 | StreamHub는 하루 1,500억 건을 수집하고 2,250억 건 넘게 전달해요 | 평균 초당 168만 건, 최대 초당 320만 건을 다룬 운영 사례예요 |
| 전환 배경 | Kinesis의 샤드 비용, 장기 보관 비용, 소비자 확장 제약을 줄이려고 Kafka로 옮겼어요 | 서비스 선택보다 트래픽 규모에 따른 비용·복구 조건을 함께 볼 수 있어요 |
| 저장 구조 | 최근 5분 데이터는 EBS에, 과거 데이터는 S3에 보관해요 | 실시간 소비와 대규모 재처리가 같은 디스크 IOPS를 두고 다투는 상황을 줄였어요 |
| 실제 병목 | CPU보다 브로커별 네트워크, EBS, 원격 복사 지연이 먼저 한계에 닿았어요 | 클러스터 평균만 보면 놓치기 쉬운 장애 신호를 보여줘요 |
| 복구 설계 | 레이트 리밋, Kafka 쿼터, 클러스터 분할, 별도 페일오버 경로를 뒀어요 | 관리형 Kafka도 애플리케이션 쪽 보호 장치와 독립 복구 경로가 필요해요 |
1. Kinesis를 Kafka로 바꾼 뒤에도 확장은 끝나지 않았어요
하루 220억 건에서 1,500억 건으로 커졌어요
StreamHub에는 Atlassian 제품의 클릭, 노출, API 호출, CDC 이벤트, 텔레메트리가 흘러요. 현재 하루 1,500억 건을 수집하고 2,250억 건 넘게 전달해요. 평균 처리량은 초당 약 168만 건이며, 피크에는 초당 320만 건을 넘어요. 예전 하루 220억 건과 비교하면 수집량이 약 6.8배로 늘어난 셈이에요. 2
Kinesis는 하루 200억~300억 건 구간까지 운영 부담이 적었어요. 규모가 5배 가까이 커지자 샤드 수와 비용이 트래픽에 따라 함께 늘었어요. 여러 소비자 그룹이 같은 샤드의 송신 용량을 나눠 쓰는 구조도 부담이 됐어요. 24시간을 넘는 보관에는 추가 비용이 들었고, 장애 뒤 데이터를 다시 읽거나 모델 학습 데이터를 재처리하려면 최대 7일 보관이 필요했어요.
Atlassian은 운영 인력이 브로커 패치와 하드웨어 교체에 매달리지 않도록 AWS MSK를 골랐어요. Kafka는 소비자 그룹을 늘리기 쉽고 며칠 치 데이터를 보관하는 비용 구조도 Kinesis보다 잘 맞았어요. 멀티클라우드로 확장할 수 있다는 점도 선택에 영향을 줬어요.
최근 데이터와 과거 데이터를 다른 저장소에 뒀어요
Kafka 계층형 저장소는 최근 5분의 데이터를 브로커 EBS에 남겨요. 실시간 소비자는 지연이 낮은 로컬 데이터를 읽어요. 닫힌 로그 세그먼트는 백그라운드 작업이 S3로 옮기고, 최대 7일 치 과거 데이터를 보관해요. 5분 넘게 뒤처진 소비자가 S3에서 읽을 때 수백 밀리초가 더 걸리지만, 이미 지연된 재처리 작업에는 감당할 수 있는 수준이라고 봤어요.
이 구조로 최악의 보관 상황에 맞춰 비싼 EBS를 미리 크게 잡을 필요가 줄었어요. 과거 데이터를 대량으로 읽는 백필 작업도 실시간 소비자가 쓰는 로컬 디스크 IOPS를 잠식하지 않게 됐어요. 저장 비용을 줄이는 효과는 분명했지만, 로컬 브로커의 여유 공간과 원격 복사 성능까지 없애 주지는 않았어요.
브로커 평균보다 가장 뜨거운 구간이 먼저 무너졌어요
대규모 Kafka에서 먼저 닿은 한계는 CPU만이 아니었어요. 생산자 입력, 복제, 소비자 전송, 리전 간 릴레이, 재시도, S3 원격 복사가 브로커의 네트워크와 EBS를 함께 사용했어요. 클러스터 평균은 여유로워 보여도 특정 브로커나 파티션은 포화 상태에 가까울 수 있었어요.
작은 인스턴스는 이벤트를 받아들이는 속도보다 복제하고 전달하며 S3로 옮기는 속도가 느려질 수 있어요. 원격 복사가 밀리면 로컬 디스크에 데이터가 계속 쌓여요. 입력량이 큰 상태에서는 지연되는 매분마다 복구해야 할 데이터도 늘어요. Atlassian은 브로커별 입력·출력, EBS 처리량, 원격 복사 지연, 파티션 쏠림, 소비자 지연을 묶어서 보기 시작했어요.
보관 기간을 7일에서 21일로 늘렸다가 다시 7일로 줄인 사례도 있어요. 오래된 객체를 한꺼번에 지우는 요청이 몰리면서 평소의 원격 쓰기와 경쟁했어요. S3 용량이 부족했던 게 아니라, 대량 삭제가 제어 영역과 데이터 영역의 API 활동을 급격히 늘린 상황이었어요. 원격 쓰기가 늦어지자 브로커의 로컬 디스크 사용량도 빠르게 올랐어요.
관리형 서비스의 제어 영역도 복구 시간을 늘렸어요
디스크가 차오를 때 저장 용량을 조금씩 늘리는 방식은 위험했어요. MSK의 저장소 변경에는 다음 변경까지 기다려야 하는 제한 시간이 있어요. 첫 증설량이 적으면 디스크가 다시 가득 차도 곧바로 추가 증설을 할 수 없어요. Atlassian은 장애 중 용량을 늘릴 때 예상 적체량과 제한 시간 전체를 버틸 여유를 한 번에 확보하는 쪽으로 바꿨어요.
브로커 인스턴스 변경도 즉시 끝나지 않아요. 원문 사례에서는 브로커 한 대의 롤링 재시작에 약 15분이 걸렸어요. 큰 클러스터 전체를 바꾸면 몇 시간이 필요해 실시간 장애 대응 수단으로 쓰기 어려워요. 브로커를 추가해도 기존의 뜨거운 파티션과 리더를 재배치하기 전까지는 과부하가 그대로 남아요. 재배치 자체가 네트워크와 디스크, 복제 부하를 더해 장애 중 확장에 제약을 줘요.
가용 영역 장애 때는 데이터 영역만 살아 있다고 충분하지 않았어요. 클러스터가 복구 중이라는 상태로 잠기자 브로커 재시작, 확장, 디스크 증설, 자동 재배치 같은 관리 작업이 막혔어요. 관리형 서비스가 일상적인 운영 부담을 줄여 줘도, 장애 복구가 같은 제어 영역에 전부 기대면 대응 선택지가 줄어요.
Kafka 앞뒤에 보호 장치와 탈출 경로를 추가했어요
StreamHub는 테넌트, 토픽, 생산자, 트래픽 등급별로 입력 속도를 제한해요. 형식이 잘못됐거나 반복해서 실패하는 이벤트는 정상 경로에서 격리해요. Kafka 안에서는 생산자와 소비자별 대역폭 쿼터를 적용해 한 파이프라인이 브로커 자원을 독점하지 못하게 막아요.
큰 클러스터는 여러 샤드로 나눠 장애 범위를 줄였어요. 주 클러스터가 오래 불안정하면 인프라 코드로 새 클러스터를 준비하고, 기존 복구와 병행해 생산자와 소비자의 이동을 판단해요. 심한 장애가 난 샤드의 트래픽을 건강한 샤드로 돌리는 초기 대응 목표는 약 15분이에요. 별도 클러스터 준비에는 약 2시간을 잡았어요.
글로벌 서비스의 페일오버는 데이터 위치 규정도 지켜야 해요. Atlassian은 같은 규제 경계 안에 미리 승인한 동반 리전을 정했어요. 주 리전이 불안정할 때 생산자와 소비자를 이 리전으로 옮길 수 있도록 경로를 준비했어요. 장애가 난 뒤 이동 가능한 지역을 새로 고르는 대신, 평소에 규정과 라우팅 조건을 확인해 둔 방식이에요.
왜 중요한가요
이 사례는 관리형 Kafka를 선택한 뒤에도 팀이 직접 책임져야 할 범위를 구체적으로 보여줘요. 클라우드 사업자가 브로커 운영을 맡아도 파티션 쏠림, 네트워크 한계, EBS 처리량, S3 요청 패턴, 제어 영역 장애는 서비스 설계에 남아요. 플랫폼 팀은 클러스터 전체 평균보다 가장 뜨거운 브로커의 피크와 복구 중 추가 부하를 기준으로 용량을 잡아야 해요. 2
계층형 저장소를 도입할 때도 저장 비용만 계산하면 부족해요. 원격 복사가 밀리는 동안 버틸 로컬 디스크, 보관 기간 변경이 만드는 S3 요청, 백그라운드 작업에 필요한 네트워크와 CPU를 함께 계산해야 해요. 보관 정책 변경은 일반 설정 수정이 아니라 트래픽이 큰 운영 작업으로 다루는 편이 안전해요.
장애 대응에서는 확장보다 빠른 보호 장치가 먼저 작동했어요. 입력 레이트 리밋과 격리 경로는 잘못된 트래픽이 공유 브로커를 압박하기 전에 막아요. 쿼터는 한 소비자나 생산자가 다른 워크로드까지 느리게 만드는 범위를 줄여요. 별도 페일오버 클러스터와 동반 리전은 관리형 서비스의 제어 영역을 쓸 수 없을 때도 복구 선택지를 남겨요.
참고 자료
'IT & AI' 카테고리의 다른 글
| PostgreSQL MVCC의 비용, 다른 DB는 어디로 옮길까요? (0) | 2026.08.10 |
|---|---|
| SQLite는 신뢰성을 어떻게 설계했을까요 (0) | 2026.08.10 |
| AI가 코드를 싸게 만들면, 저장소에는 무엇을 남겨야 할까 (0) | 2026.08.10 |
| 32TB도 42분, PlanetScale이 백업을 복원하며 다음 백업을 만드는 이유 (0) | 2026.08.10 |
| AI가 만든 듯한 화면을 피하는 디자인 스킬, Hallmark (0) | 2026.08.10 |