[Spring Boot, WebSocket, Kafka, MongoDB] 채팅 기능 구현#2. 도메인 설계
이전 글에서는 채팅 기능에 WebSocket, Kafka, MongoDB를 사용하는 이유에 대해 작성해보았다.
이번에는 채팅 기능에서 사용되는 도메인 설계에 대해 작성해보려 한다.
도메인 설계
채팅 기능에 사용되는 도메인과 저장되는 저장소 목록은 다음과 같다.
- 채팅방(ChatRoom): RDBMS
- 채팅 메시지(ChatMessage, Message): MongoDB
- 채팅 알림(ChatNotification, Notification): RDBMS
- 채팅방 입장 상태 (ChatRoomParticipant): REDIS
채팅방(ChatRoom)
채팅방은 사용자들이 서로 메시지를 주고받을 수 있는 공간으로, 관계형 데이터베이스(RDBMS)에 저장된다. 채팅방 정보는 사용자 정보와 긴밀히 연결되어 있어, 조회 시 사용자 정보를 함께 제공해야 하는 경우가 많다. 이러한 요구사항을 효율적으로 충족하기 위해, RDBMS(MySQL, MariaDB)를 사용하여 채팅방과 사용자 정보를 연결하고, FETCH JOIN을 통해 한 번에 조회하는 방법을 선택하였다.
ChatRoom
- 채팅방에 참여한 두 사용자(sender와 recipient)를 LAZY_LOADING 방식으로 관계를 맺었다.
채팅 메시지(ChatMessage, Message)
채팅 메시지는 MongoDB에 저장되는 ChatMessage와 Kafka 토픽에 저장되며 WebSocket을 통해 사용자에게 전달되는 Message로 구분된다. ChatMessage는 chatType 필드를 통해 텍스트 메시지와 이미지 메시지를 구분한다. 텍스트 메시지의 경우 imageName과 imageUrl 필드는 null로 설정된다. 또한 메시지 구조의 경우 새로운 기능 추가 시 변경될 가능성이 있기 때문에, 스키마리스(Schema-less) 특성을 가진 MongoDB를 사용하여 데이터 구조의 변화에 유연하게 대응할 수 있도록 하였다.
ChatMessage
- 채팅 메시지의 경우, 주로 채팅방 ID를 통해 조회된다.
- 채팅방 ID 필드에 @Indexed 어노테이션을 작성하여, 조회 성능을 향상시킨다.
- createdAt 필드는 ZonedDateTime 값을 사용하여 특정 시간대에서의 시간을 정확히 표현하고, 문자열로 변환하여 저장한다.
- 사용자가 메시지를 보낸 시간을 정확히 기록하고 조회할 수 있다.
참고
https://mslilsunshine.tistory.com/175
Message
- Apache Kafka는 메시지를 바이트 배열로 전송하기 때문에, 메시지 직렬화, 역직렬화 과정은 필수적이다.
채팅 알림(ChatNotification, Notification)
채팅 알림 역시 데이터베이스에 저장되는 ChatNotification과 Kafka 및 WebSocket을 통해 사용자에게 전달되는 Notification으로 구분된다. 채팅 알림을 조회할 때 사용자 정보를 함께 제공해야 하는 요구사항을 충족하기 위해, 성능상의 이점이 있는 RDBMS에 ChatNotification을 저장합니다.
채팅방 입장 상태(ChatRoomParticipant)
채팅방 입장 상태는 사용자가 채팅방에 입장하거나 메시지를 전송할 때 상대방의 입장 상태를 판단하는 데 사용된다. 이 정보는 자주 조회되며, 데이터의 손실이 시스템 동작에 큰 영향을 미치지 않는다. 따라서, 빠른 데이터 접근이 가능하고 일시적인 데이터 저장에 적합한 메모리 기반 데이터베이스인 Redis에 저장하는 것이 효율적이라 판단하였다.