사이드 프로젝트를 진행하면서 채팅 기능을 담당하게 되었다.
채팅 기능에 대한 요구사항
프로젝트에서 사용할 기술에 대해 회의를 진행하면서 외부 브로커를 사용하기로 결정하였다. 왜냐하면, 프로젝트의 인프라 환경은 단일 서버이지만, 채팅 기록을 저장해야하는 요구사항이 있기 때문이다.
즉, 단일 서버이지만, 데이터베이스에 채팅 기록을 저장하기 위해 디스크 I/O가 발생하기 때문에 latency를 낮추기 위해 외부 브로커를 사용하기로 결정하였다.
이처럼 채팅 서비스를 구현하기 위해서 어떤 Pub/sub 메시지 브로커를 사용할 것인지 결정해야한다.
대표적으로 Redis와 Kafka가 존재한다.

우선 Redis에 대해 알아보자.
Redis는 NoSQL DB, In-Memory DB, PUB/SUB 등으로 다양하게 사용되는데 서로 다른 서버에서 채팅 메시지를 수신하기 위해서 사용되는 PUB/SUB에 대해 알아보려고한다.
Redis Pub/Sub의 가장 큰 특징으로는, In-Memory 기반이기 때문에 low-latency로 메시지를 구독자들에게 전달할 수 있지만, 메시지가 영속적으로 저장되지 않는다.
그리고 Redis Pub/Sub은 발행자가 메시지를 Publish 하는 순간, 해당 채널을 구독한 구독자들에게 메시지를 바로 전달한다.(Push 모델)
즉, 구독자들은 메시지를 발행한 시점에만 메시지를 전달 받을 수 있다는 것이다.
만약에 채널에 대해 구독자들이 없다면 메시지가 발생되어도 바로 사라진다는 것이다.

이번에는 Kafka에 대해 알아보자.
Kafka는 분산, 수평 확장 가능한 Pub/Sub 메시지 시스템이며, 특징으로는 High-Throughput, High-Availability, fault-tolerant가 있다.
Kafka는 Producer가 Topic에 이벤트를 보내면, 해당 이벤트를 Topic의 각 Partition에 분산하여 저장한다. 그리고 Consumer는 주기적으로 Topic에 메시지가 있는지 확인하고 Polling하여 Consumer가 메시지를 가져온다.
그리고 Consumer가 메시지를 가져가더라도 Topic의 메시지가 바로 삭제되지 않는다.
-> 보관주기/용량이 넘어가면 삭제된다.
그리고 메시지를 Polling하는 Consumer는 Group으로 관리되며, Group내 Consumer는 각각 1개 이상의 Partition으로부터 이벤트를 가져온다.
Redis의 Pub/Sub과 Kafka를 비교해보았을 때, 현재 우리 프로젝트에 알맞은 기술은 Redis를 사용해야할 것 같다는 생각이 들었다.
일반적으로 Kafka를 사용하는 이유는 대표적으로 고가용성과 신뢰성 등이다.
실시간 채팅이라는 기능을 고려했을 때, Kafka보다는 매우 빠른 인메모리 기능을 제공하는 Redis를 사용하는 것이 성능이 더 좋을 것 같다는 생각이 들었다.
그러면 단일 서버 환경이면서, 외부 DB를 따로 구축할 것이면, Redis를 사용하지 않고, STOMP의 내부 브로커가 메시지를 전달받았을 때, 외부 DB에 저장하는 것이 좋지 않을까? 라는 생각도 들었다.
Redis Pub/Sub 를 사용하는 것이 옳은 선택일까...?
다시 한 번 고민해본 결과, 단일 서버 환경이고, 트래픽도 많지 않으며, 앞으로 서버 확장 가능성도 거의 없다고 판단했다. 그렇기 때문에 굳이 외부 메시지 브로커를 둘 필요가 없다고 생각했다. 따라서 STOMP 내부 브로커를 사용하더라도 메시지 전달 자체는 충분히 안정적일 것이라고 판단했고, 현재 시스템 규모와 복잡도를 고려했을 때, 외부 메시지 브로커 도입은 좋은 선택은 아니라고 판단했다.
결론적으로 현재 트래픽 수준과 시스템 확장 가능성을 고려했을 때, 외부 메시지 브로커를 따로 두지 않기로 결정했다.