스크랩

Kafka 순서 보장과 처리량, 둘 다 잡을 수 있을까? Airbridge의 Project Differential 사례

Kafka 순서 보장과 처리량, 둘 다 잡을 수 있을까? Airbridge의 Project Differential 사례

핵심 요약

광고 어트리뷰션 플랫폼 Airbridge가 이벤트 처리 파이프라인을 개편한 사례를 소개합니다. 클릭·설치·구매 같은 이벤트를 실시간으로 매칭하려면 단순히 빠른 것만으로는 부족하고, 필요한 순서대로, 유실·중복 없이 처리해야 하는데요. 기존 마이크로 배치 구조의 한계를 넘기 위해 설계한 Project Differential로 처리 속도를 10배 이상 끌어올렸다고 합니다.

기존 방식의 문제: 순서는 지켰지만 워커가 논다

기존 구조는 Kafka 메시지를 마이크로 배치로 가져와 이벤트 종류별로 순차 처리하는 방식이었습니다.

  • 순서 제어는 쉬웠지만, 앞선 이벤트 처리를 기다리는 동안 다른 워커가 유휴 상태가 되는 비효율이 발생했습니다.
  • 워커별 처리 속도 차이에 hot partition 문제까지 겹치면, 서버를 아무리 증설해도 처리 속도가 정체되는 상황에 부딪혔습니다.

스케일 아웃이 답이 되지 않는 지점에 도달한 것이죠.

Project Differential: 순서 보장의 범위를 다시 정의하다

새 설계의 핵심은 "전역 순서"라는 이상을 내려놓고, 비즈니스에 실제로 필요한 순서만 지키는 것입니다.

1. 마이크로 배치 제거, 이벤트 종류별 독립 Consumer

이벤트 종류별 Consumer가 같은 Kafka topic을 독립적으로 읽습니다. 서로 기다릴 필요가 없어지니 유휴 시간이 사라집니다.

2. Partition 단위 순서 보장

순서 보장은 topic 전체가 아닌 partition 단위로 수행합니다. 순서가 중요한 동일 사용자 흐름의 이벤트가 가능한 한 같은 partition에 들어가도록 구성해, 정말 필요한 곳에서만 순서를 지킵니다.

3. Consumer 간 "안전거리" 유지

뒤따르는 Consumer는 앞선 Consumer의 처리 위치를 추월할 수 없으며, offset 또는 event time 기준의 안전거리를 둡니다. 앞선 Consumer가 처리하지 않는 메시지는 다음 Consumer에게 넘겨 재사용하고, 버퍼가 가득 차면 Kafka를 직접 읽는 Polling Mode로 전환하는 유연함도 갖췄습니다.

내부 구현 살펴보기

내부적으로는 몇 가지 컴포넌트가 이 규칙을 강제합니다.

  • ConsumerSuite / PartitionedConsumerChain: partition별로 Consumer 체인을 관리합니다.
  • LimitedEventProcessor: 앞선 Consumer의 checkpoint를 넘지 않도록 처리 범위를 제어합니다.
  • CommitManager: 버퍼링·비동기 처리 중에도 실제 완료된 연속 offset만 Kafka에 commit하도록 관리해 유실과 중복을 막습니다.

결과와 시사점

테스트 운영에서 이벤트 유실·중복 없이 동작하는 것을 확인했고, 기존 마이크로 배치 방식 대비 10배 이상의 처리 속도 향상을 달성했습니다.

이 사례가 흥미로운 이유는 기술적 완벽함 대신 실용적 타협을 택했다는 점입니다. 완전한 전역 순서를 만드는 대신, 실제 비즈니스에 필요한 순서를 best effort로 지키면서 처리량을 확보한 것이죠. 분산 시스템에서 "어디까지 보장할 것인가"를 고민 중인 분들에게 좋은 참고가 될 만합니다.

향후에는 구조 단순화, Spot Instance 종료 상황에 대응하는 adaptive flow control, 순차 처리 자체를 줄이는 아키텍처 개선을 검토 중이라고 하니, 후속 소식도 기대해 볼 만합니다.

원문: 순서대로, 한 번만, 빠르게 - Airbridge Engineering (GeekNews 소개 글 기반)


원문: https://news.hada.io/topic?id=31433