안녕하세요.
이번 편에서는 채팅 메세지를 저장하고 조회하는 메커니즘을 어떻게 구현했는지에 대해서 설명하도록 하겠습니다.
1. 채팅 메세지 저장 및 조회
채팅 메세지의 영구적인 저장소로는 Elastic Search를 사용했습니다.
Elastic Search를 영구적인 저장소로 채택한 기술적 선택 이유는 아래와 같습니다.
- 역색인 구조(Inverted Index)로 데이터를 저장하므로 키워드, 조건 등의 검색 성능이 높음
- 정형화된 데이터가 아닌 비정형 데이터를 저장하기 위해 사용됨
채팅 메세지를 조회할 때 주로 특정 채팅방, 특정 시간 이후 등의 조건으로 검색하고, 또한 채팅 메세지는 정형화된 데이터로 다른 데이터와 특정한 관계를 맺지 않는 비정형 데이터이기 때문에 Elastic Search를 활용하여 저장하였습니다.
하지만, Elastic Search은 관계형 데이터베이스와 같이 트랜잭션을 지원하지 않고 아래의 메커니즘으로 데이터가 저장됩니다.
- 샤딩: Document ID와 샤드 개수를 기반으로 어느 샤드에 저장할지 결정하여 데이터를 전송
- Document를 메모리 버퍼 및 Translog(쓰기 로그)에 저장함
- 메모리 버퍼는 특정 주기에, 또는 버퍼 Full이면 불변 Lucene 세그먼트로 변환됨
- 리프레시 : 일정한 주기로 발생하고, 신규 저장된 Document는 리프레시 이후에 검색이 가능함
- Flush : 일정 주기 또는 Translog Full이면 Translog를 디스크에 저장하고 Translog를 비움
채팅방 재입장 등의 이유로 채팅 메세지 조회 서비스가 필요하면, 적어도 리프레시가 동작한 이후에만 최신 데이터를 불러올 수 있음을 의미했습니다. 반대로 말하면 리프레시가 발생하지 않은 상태에서 채팅 메세지를 조회하면, 최신 데이터를 불러오지 않으므로 이에 대한 대책이 필요했습니다.
그래서, 아래와 같은 채팅 메세지 저장소는 Elastic Search 뿐만 아니라 Redis를 캐시로 앞단에 추가하여 아래와 같은 구조로 생성하였습니다.
채팅 메세지 저장 시, Elastic Search 뿐만 아니라 Redis에도 저장하도록 하였습니다. 이를 통해서 Elastic Search의 세그먼트 Refresh 정책으로 인하여 채팅 메세지가 최신으로 동기화되지 않은 타이밍 문제를 해결할 수 있었습니다.
Redis Cache에는 채팅방:id -> [채팅 메세지 List] 형태로 저장하고 LPUSH 및 LTRIM을 활용하여 최신 채팅 메세지를 저장했습니다. 채팅 메세지 입장 시, Redis Cache로 부터 데이터를 최초로 읽고 스크롤을 통하여 과거 메세지가 필요할 때는 Elastic Search를 통해 데이터를 페이징 조회할 수 있도록 구현하였습니다.
2. 채팅방 입장 및 채팅 메세지 조회 동시성 이슈
웹 소켓을 통하여 채팅방에 메세지를 전송하면, 웹 소켓을 통한 메세지 전달, Redis 저장, 그리고 Elastic Search 저장 3가지가 발생합니다. 채팅방에 입장하면, Redis에 저장된 최신 채팅 메세지를 조회합니다. 만약 채팅방 입장 요청과 채팅 메세지 조회 요청이 동시에 발생하면 미묘한 타이밍으로 인하여 채팅 메세지를 정상적으로 불러올 수 없는 잠재적인 문제도 있다고 생각했습니다.
그러나, Redis Cache를 도입하여 이 문제를 해결할 수 있었습니다. Redis는 싱글 스레드로 동작하므로 채팅방 입장 및 채팅 메세지 조회 요청을 순차적으로 처리할 수 있도록 만든다는 장점이 있었습니다.
3. Redis 관련 정리 내용
Redis를 활용하기 위해 인터넷 자료와 참고 서적 등의 내용을 정리한 링크입니다.
https://github.com/chrismrkr/WIL/blob/main/infrastructure/redis/redis-summary.md
WIL/infrastructure/redis/redis-summary.md at main · chrismrkr/WIL
what I Learned. Contribute to chrismrkr/WIL development by creating an account on GitHub.
github.com
해당 기능을 구현하면서 Elastic Search에 대해서는 많이 알아보지 못했지만, Redis에 대해서 꼼꼼하게 학습해볼 수 있다는 점에서 흥미로웠습니다.
다음 편에서는 채팅 메세지 키워드 검색 등의 기능을 구현하며 Elastic Search에 대해서 더 자세히 작성해볼 계획입니다.
감사합니다.
'사이드 프로젝트 > 채팅 프로그램 개발 프로젝트' 카테고리의 다른 글
웹 채팅 프로그램 개발 프로젝트 후기 - 1 (3) | 2024.12.02 |
---|---|
웹 채팅 프로그램 개발 프로젝트 후기 - 3 (1) | 2024.11.23 |
웹 채팅 프로그램 개발 프로젝트 후기 - 2 (2) | 2024.11.23 |