피드로 돌아가기
컬리 기술블로그Backend
원문 읽기
컬리 검색이 카프카를 들여다본 이야기 2
컬리가 Redis 기반 검색 인덱싱 파이프라인을 Kafka Streams + Spring으로 전환해 메시지 병합 로직을 자동화하고 헬스체크 기능을 확보
AI 요약
Context
검색 인덱싱을 위해 서로 다른 두 개의 Kafka 토픽에서 수신한 메시지를 조합해야 했지만, 초기 구현은 Redis를 중간 저장소로 사용하여 복잡성이 높았다. 또한 메시지 처리 중 오류 발생 시 Kafka Streams 스레드가 동작을 멈춰도 Spring 애플리케이션의 헬스 상태는 정상으로 표시되어 운영상 문제가 발생했다.
Technical Solution
- 메시지 병합 로직을 Kafka Streams로 구현: KStream과 KTable을 join하여 같은 키를 가진 메시지를 자동으로 결합
- Kafka Streams 클라이언트를 Spring에 의존 주입: @EnableKafkaStreams 어노테이션과 StreamsBuilder bean을 활용해 Spring이 생명주기를 관리하도록 변경
- KafkaStreamsConfiguration bean 추가: APPLICATION_ID, BOOTSTRAP_SERVERS, NUM_STREAM_THREADS 등 설정을 Spring 설정 클래스에서 정의
- HealthIndicator 구현으로 상태 모니터링 추가: StreamsBuilderFactoryBean을 주입받아 Kafka Streams 클라이언트 상태(CREATED, RUNNING, RE-BALANCING, ERROR, NOT_RUNNING, PENDING_SHUTDOWN)를 주기적으로 확인
- 에러 상태 감지 시 즉시 알림: Health check를 통해 ERROR/NOT_RUNNING/PENDING_SHUTDOWN 상태 감지 시 Health.down()으로 애플리케이션 상태 변경
Key Takeaway
Kafka Streams를 Spring Framework에서 관리하면 분산 메시지 처리 로직과 애플리케이션 생명주기를 통합할 수 있으며, HealthIndicator를 통해 스트림 처리 오류를 운영 관점에서 가시화할 수 있다.
실천 포인트
여러 Kafka 토픽의 메시지를 조합해야 하는 검색/추천 시스템에서 Kafka Streams의 join 연산을 Spring bean으로 관리하면 Redis 같은 중간 캐시 계층을 제거하면서도 메시지 병합 로직을 선언적으로 구현할 수 있다. 동시에 @Autowired StreamsBuilder 패턴으로 스트림 클라이언트의 생명주기를 Spring이 관리하도록 하면, HealthIndicator를 통해 처리 오류를 애플리케이션 상태로 노출시켜 운영 자동화를 구현할 수 있다.