카프카 활용한 채팅 어플리케이션 만들기 - (계획 - 2)

600g (Kim Dong Geun)·2021년 8월 1일
1

채팅 어플리케이션을 어떻게 구현할지에 대해서 좀 더 생각을 해봤습니다 ㅎㅎ..

카프카는 기본적으로 pull based pub/sub 형태를 띄고 있어서, 데이터의 분산 처리에 용이합니다만

채팅 같은 경우는 producer가 메시지를 queue에 전달하면, 구독하고 있는 모든 consumer server가 읽고 사용자에게 동일한 메시지 요청을 전달해야합니다.

그러나, 위에 언급했듯이 카프카는 Pull based pub/sub 구조를 띄고있고 하나의 queue 그룹에 보관된 데이터를 consumer server 가 pull로 가져오는 형태입니다.

즉, 컨슈머 그룹내에서 다른 컨슈머가 처리한 데이터에 대해서는 처리하지 않기 때문에 사용자는 메시지를 뜨문 뜨문 전달 받게됩니다.

그러니까 예시를 들어서 설명하자면

첫번째 terminal은 프로듀서이고 나머지는 그 프로듀서를 구독하고 있는 컨슈머 들인데,
프로듀서가 전달한 데이터를 분할해서 처리를 하고 있습니다.

채팅의 특성상 소켓(혹은 특정 방에 참가한 유저들)은 구독하고 있는 모든 채팅 내용들이 그대로 전달되어야 되는데, 이렇게 내가 보낸 메시지들이 조각나서 컨슈머로 전달이 된다면, 문제점을 해결할 수 없는 구조가 됩니다.

따라서 그 구조를 해결하기 위한 2가지 아키텍쳐로 생각을 해봤습니다.

구조

1안

사용자가 채팅 메시지를 프로듀서로 전달하면, 프로듀서는 브로커에 존재하는 모든 파티션에 데이터를 재생산하여 전달하는 방법

장점
  • 브로커 개수는 비교적 자유롭게 늘릴 수 있으므로, 확장하기 쉬워집니다.
  • 또한 구독하고 있는 소켓과 독립적으로 메시지를 처리하기 때문에 확장에 용이한 구조입니다.
  • 즉 아프리카 TV나 대규모 동영상 스트리밍 채팅 플랫폼에서도 사용가능한 구조라 생각됩니다.
단점
  • 단, Producer가 모든 Partiton 갯수만큼 데이터를 전송하는 구조이기 때문에 브로커의 처리 비중이 굉장히 커지게 됩니다.
  • 파티션 개수가 n개 브로커 개수가 m개이면 한개의 메시지를 처리하는데 n/m 개의 요청을 브로커가 처리 해야 됩니다.
  • 컨슈머가 여러 partition을 담당하게 된다면 컨슈머 단에서 중복 처리 할 수 있으니, patrition- consumer의 비율을 1:1로 유지하거나 추가적인 분리 요청 처리가 필요할 것 같습니다.
  • 또한 카프카는 파일시스템에 데이터를 저장하기 때문에 부하는 부하대로, 용량은 용량대로 차지 하지 않을까라는 생각이 듭니다.

근데 이럴꺼면 Redis를 쓰는게 낫지 않냐 라는 생각이 들기 시작했습니다.

2안

프로듀서가 메시지를 생산하면 커스텀 파티셔너를 통해서 특정 파티션에만 데이터를 전달하는 방법

  • 1안과 달리, 브로커는 1건의 데이터 요청은 그대로 1건의 데이터로만 요청을 처리하면 되기 때문에 브로커의 비중을 줄일 수 있습니다.
  • 파티션을 할당하는 Key는 RoomId로 생각
  • 다만 특정방에 있는 유저들을 어떻게 특정 컨슈머 서버 소켓에 매칭 할 것인가..는 조금더 고민해 볼 문제인 것 같습니다.
  • 만약 아프리카나, 네이버 TV 처럼 한 Room에 많은 사용자가 몰아져야 한다면 결국 특정 파티션에만 부하가 몰릴 것이기 때문에, 한 Room 에 사용자가 많은 구조라면 적합하지 않다.

여기서 1안, 2안 모두 해결해야할 문제점이 굉장히 명확하게 보이고..
레디스를 사용하는게 낫지 않나 라는 생각이 스멀스멀 기어오르고 있습니다.

그러나 카프카를 위한 토이프로젝트이기 때문에, 채팅시스템 with 카프카 with 레디스가 되어야 할 것 같습니다...

뭔가 프로젝트 아키텍쳐가 복잡해지고 있고 제머릿속도 복잡해지고 있지만, 괜찮습니다.

아직 계획일 뿐이니까요.. ㅎㅎ

일단 부하테스트도 모두 해볼 생각이기 때문에,

채팅시스템 With 1안, 채팅시스템 With 레디스, 채팅시스템 With 카프카, Redis 로 구현하여 스트레스 테스트를 해보고 비교해보고 결과를 정리하면, 적재적소에 어떤 프레임워크를 사용할지 체감할 수 있을 것 같습니다!

채팅시스템 With 레디스, 채팅시스템 With 카프카, Redis 는 다음 포스팅에 그 구조를 올리 도록 하겠습니다.

profile
수동적인 과신과 행운이 아닌, 능동적인 노력과 치열함

2개의 댓글

comment-user-thumbnail
2022년 1월 25일

안녕하세요, 좋은 포스팅 감사합니다.
1안에서 파티션 개수가 n개 브로커 개수가 m개이면 한개의 메시지를 처리하는데 n/m 개의 요청을 브로커가 처리 해야 됩니다. 의 설명에서는 왜 브로커가 n/m 개를 처리하게 될까요?
브로커의 경우는 복제해서 사용하기 때문에 동일하게 n개를 처리할 것 같은데, 제가 잘 몰라서 여쭤봅니다 😂

1개의 답글