카카오뱅크, 하루 N억 건 알림 발송기 재구축: 성능과 단순성 모두 잡은 아키텍처
핵심 내용
카카오뱅크가 Service/Core Layer 분리와 Age-Based Work-Stealing을 적용해 10,000 TPS와 낮은 지연시간을 달성하며 발송기를 재구축했다.
자세히 보기
카카오뱅크 알림경험엔지니어링팀은 하루 N억 건의 알림을 처리하는 발송기(UMS)를 재구축하며, 성능 최적화와 개발자 멘탈 모델 단순화라는 두 마리 토끼를 잡았다. 기존 시스템은 Thread Pool 미사용과 단일 큐 구조로 인해 Head-of-Line Blocking이 발생했고, P99 Latency의 80%가 대기 시간으로 소모되는 병목 현상을 겪었다.
Service/Core Layer 분리를 통한 복잡성 격리
신규 아키텍처는 복잡한 성능 로직을 Core Layer에 캡슐화하고, 개발자가 비즈니스 로직에만 집중할 수 있도록 Service Layer에 단순한 인터페이스를 제공한다. Service Layer 개발자는 RequestHandler와 Sender 인터페이스의 총 3개 메서드만 구현하면 되며, 재시도나 타임아웃 같은 복잡한 제어는 Core Layer가 담당한다. 이를 통해 Sender 벤더 교체나 Core Layer 내부 최적화 변경 시 Service Layer 코드 수정이 불필요해져 확장성과 유지보수성이 크게 향상되었다.
Age-Based Work-Stealing과 Lock-Free 구현
Core Layer에서는 높은 처리량을 위해 Age-Based Work-Stealing 기법을 도입했다. 중앙 관리자가 100ms마다 큐를 스캔하여 대기 시간(Age)이 긴 작업을 유휴 Worker에게 분배함으로써, 느린 작업 뒤에 따른 빠른 작업의 대기 시간을 대폭 단축했다. 예를 들어 2000ms 대기하던 작업이 600ms로 처리 시간이 단축되는 효과를 보였다.
또한 초당 10,000건 이상의 Steal 연산을 처리하기 위해 Lock-Free 구조를 채택했다. CAS(Compare-And-Set)와 Barrier를 조합해 원자적 분할을 결정하며, Zero-Copy 기법으로 배열 복사 없이 인덱스 조정만으로 큐를 분할해 메모리 할당과 GC 압박을 최소화했다. 고정 크기 Array를 사용해 CPU 캐시 효율을 극대화하고, Kotlin inline class와 템플릿 캐싱을 통해 객체 오버헤드를 제거했다.
성과 및 시사점
재구축 결과 10,000 TPS 이상의 처리량과 P99 Latency 200ms 미만을 달성했다. 신규 채널 추가 기간이 단축되었으며, 개발자들은 동시성이나 성능 최적화 로직을 이해하지 않고도 알림 발송 기능을 개발할 수 있게 되었다. 이는 기술적 복잡성을 숨기고 단순한 인터페이스를 제공함으로써 팀 전체의 개발 속도를 높인 구조적 접근의 성공 사례로 평가된다.
이 한국어 요약은 AI가 자동으로 만들었습니다. 원문의 주장과 맥락은 원문에서 확인해 주세요. 저작권은 원저작자에게 있습니다.