Project/배드민턴의 모든 것
(3) 채팅 개발 - Kafka 도입
예림밈
2025. 4. 24. 18:03
이번 포스팅은 채팅 개발에 앞서 Kafka 도입에 대해 얘기해보려고 한다.📚
1. Kafka 도입 배경
앞서 확인한 요구사항에 따르면 채팅 도메인이 많은 도메인과 의존성이 있는 것을 확인했다. 채팅 도메인을 비동기적으로 처리하지 않고 사용한다면 운동/모임 도메인 쪽에서 코드가 수정되면 채팅쪽 코드도 동시에 계속 수정해야해서 추후 유지보수에 굉장히 안좋을 것이라는 판단을 했다. 따라서 이벤트 기반 스트리밍인 Kafka를 도입하기로 했다.
2. Why Kafka?
왜 많은 비동기 처리 방식 중 Kafka를 선택했을까?! 그 이유에 대해 알아보자.
우선 Kafka의 특징에 대해 알아보자.
3. Kafka 특징
- 고성능 분산 이벤트 스트리밍 플랫폼
- Pub-Sub 모델의 메시지 큐 형태로 동작
- 이벤트 브로커 방식
** 이벤트 브로커는 publisher가 생산한 이벤트를 이벤트 처리 후에 바로 삭제하지 않고 저장하여, consumer가 특정 시점부터 이벤트를 다시 consume 할 수 있는 장점이 있다.
4. Kafka 장점
- 대규모 트래픽 처리 및 분산 처리에 효과적
- Kafka 클러스터는 쉽게 확장할 수 있어, 사용자 수가 증가해도 시스템 쉽게 확장 가능
- Kafka는 메시지를 일정 기간 저장할 수 있어 채팅 history 관리에 유용
5. kafka 구성 요소 및 특징
- Topic
- 메시지를 목적에 맞게 구분할 때 사용
- 메시지를 전송하거나 소비할 때 Topic이 반드시 존재
- Consumer는 자신에게 할당된 Topic의 메시지만 처리
- 한 개의 토픽은 한 개 이상의 파티션으로 구성 - Partition
- 분산 처리를 위해 사용
- Topic 생성 시 partition 개수를 지정 가능 (* 단 추가만 가능!)
- 파티션이 1개라면 모든 메시지에 대해 순서가 보장
- 파티션 내부에서 각 메시지는 offset(고유 번호)로 구분
- 파티션이 여러개라면 Kafka 클러스터가 라운드 로빈 방식으로 분배해서 분산처리되기 때문에 순서 보장 X
- 파티션이 많을 수록 처리량이 좋지만 장애 복구 시간이 증가됨 - Offset
- 컨슈머에서 어디까지 메세지를 읽었는지 저장
- 컨슈머 장애 발생 후 중단되었다가 다시 시작해도 마지막으로 읽은 위치부터 다시 읽어들일 수 있음 - Producer
- 메시지를 만들어서 Kafka에 전송
- 메시지 전송 시 한꺼번에 모아서 보내거나(Batch),key값을 지정하여 특정 파티션으로만 전송 가능
- 전송 acks값을 설정하여 효율성을 높일 수 있다.
- ACKS=0 -> 매우 빠르게 전송. 파티션 리더가 받았는 지 알 수 없다.
- ACKS=1 -> 파티션 리더가 받았는지 확인. 기본값
- ACKS=ALL -> 파티션 리더 뿐만 아니라 팔로워까지 메시지를 받았는 지 확인 - Consumer
- 카프카에서 메시지를 가져와 처리하는 역할
- 메세지를 Batch 처리할 수 있다.
- 한 개의 컨슈머는 여러 개의 토픽을 처리할 수 있다.
- 메시지를 소비하여도 메시지를 삭제하지는 않는다. (Kafka delete policy에 의해 삭제)
- 같은 메시지를 여러 번 읽을 수 있음
- 한 개 파티션은 같은 컨슈머그룹의 여러 개의 컨슈머에서 연결할 수 없다. - Broker
- 실행된 카프카 서버 (Kafka 서버 그 자체)
- 프로듀서와 컨슈머는 별도의 애플리케이션으로 구성되는 반면, 브로커는 카프카 자체
- Broker(각 서버)는 Kafka Cluster 내부에 존재한다.
- 메시지를 받아 저장하고, 요청이 오면 전달하는 중개자 역할을 수행한다. - Zookeeper
- Kafka 시스템 관리자 역할
- 시스탬의 상태를 감시하고, 문제가 생기면 조정하는 역할
- 분산 메시지큐의 메타 정보를 중앙에서 관리하는 역할
번외
Redis도 메시지 브로커 방식을 사용하여 같이 고려해보았지만 redis의 치명적인 단점이있다.
Redis 단점
- 메모리 기반이므로 서버가 다운되면 Redis 내의 모든 데이터가 사라짐
- 이벤트 도착 보장을 못함
결론
- Redis는 메모리 기반 데이터 저장소이기 때문에 서버가 다운되면 모든 데이터가 손실되어 이는 채팅 history를 보존하기 어려움
- 읽음 확인, 메시지 삭제 등을 구현하기에는 kafka가 더 유리
- Kafka에 비해 Redis는 확장성이 낮다고 판단
따라서 Redis로 채팅을 구현하기에는 다소 무리가 있다고 판단하였고,
이번 기회에 한 번도 사용해보지 않은 Kafka 기술을 사용해보고 싶기도 하여 Kafka로 결정하였다.
다음 포스팅에서는 kafka 본격적으로 사용하는 포스팅으로 돌아오려고한다. 👀