이 시리즈는 채팅 시스템을 구축하면서 겪은 경험을 정리한 기술 회고로,
해당 글은 채팅에서 RDB 기반 채팅 시스템에 Redis를 추가 및 구조 변경에 대해 다룹니다.
Redis vs MySQL (RDB)
MySQL 기반 시스템의 특징
- 모든 메시지를 chat_message 테이블에 시간순으로 저장
- 각 사용자의 읽음 여부는 read_point로 관리
- 채팅방 마지막 메시지, 읽지 않은 메시지 수 등을 매 요청마다 쿼리로 처리
- 실시간 수신은 WebSocket + STOMP로 처리
문제점
- 메시지 수가 많아질수록 조회 쿼리의 부하가 커짐
- 최근 메시지 + 읽음 정보 + 마지막 메시지를 한 번에 처리하기 위한 조인이 복잡함
- 수십 개 채팅방에 대해 동시에 실시간 정보를 갱신할 때 성능 저하 발생
Redis 기반 구조의 기대 효과
- 실시간성이 중요한 채팅에 적합한 In-Memory 처리
- 채팅방별 최신 메시지, 읽음 여부, 안 읽은 메시지 수 등을 ZSet, Hash, Pub/Sub으로 빠르게 관리 가능
- 빈번한 읽기/쓰기에도 빠른 처리 속도 보장
Redis 적용 로직

변경 사항
- 메시지 저장
- 메시지 수신 시 RDB뿐 아니라 Redis에도 저장
- Redis ZSet으로 채팅 메시지를 시간 기준 정렬 저장
- Redis Hash로 각 채팅방 유저들의 읽은 시간 관리
- 읽음 처리
- 사용자별 마지막 읽은 메시지 index를 Redis에 저장
- 특정 메시지 index를 기준으로 ZSet에서 count하여 안 읽은 메시지 수 계산
- 채팅방 리스트 조회
- Redis에서 각 채팅방의 마지막 메시지, 안 읽은 수, 시간 정보 등 조회 RDB 쿼리 없이 바로 응답 가능
한계
- Spring을 재시작하면 Redis 데이터가 초기화되는 문제가 발생했습니다.
- 채팅하는 과정에서 Redis와 RDB에 둘 다 동기적으로 입력을 진행하므로, 채팅하는 과정이 비효율적으로 진행됩니다.
Next
Redis를 통한 채팅을 구현했으니, Redis Stream을 통한 비동기 저장을 구현하여, 채팅 과정에서의 속도를 높여보겠습니다.