베팅덕 (실시간 베팅 서비스)



About Project
Objective
실시간 베팅의 짜릿함과 채팅의 소통 재미를 결합한 새로운 경험을 제공하는 웹 서비스. 코인으로 베팅하고, 실시간 채팅하며, 획득한 코인으로 오리를 구매해 마이페이지를 꾸미는 구조.
Tools & Technologies
TypeScript, Node.js, Redis, WebSocket, HINCRBY, Pub/Sub, MessageQueue
Challenge
트위치(Twitch)는 전 세계적으로 인기 있는 실시간 스트리밍 플랫폼으로, 한국에서도 많은 사람들이 포인트 예측 시스템을 즐겨 사용했지만 트위치가 한국에서 철수하면서 더 이상 해당 기능을 사용할 수 없게 되었습니다. 대안으로 많은 사람들이 치지직이라는 스트리밍 플랫폼을 이용하기 시작했지만, 치지직에는 베팅 서비스가 없는 점이 아쉽다는 의견이 많았습니다.
이러한 피드백을 바탕으로 "우리가 직접 베팅 시스템을 만들어보자!" 하는 생각을 계기로 프로젝트를 진행하게 되었습니다.
베팅덕에서의 베팅은 방장이 정한 두 가지 옵션 중 승산이 더 높아보이는 것에 덕(duck)코인을 거는 것을 의미합니다. 베팅이 끝나면 코인을 잃거나, 배율만큼의 코인을 획득할 수 있습니다.
사용자가 원하는 컨텐츠(유튜브, 치지직, 생방송 스포츠 등)를 시청하며 베팅을 할 수 있도록, 별도의 컨텐츠를 제공하지 않고 작은 창으로 띄워두고 베팅만을 즐길 수 있도록 구현했습니다.
비회원 로그인을 통해 사용자가 더 쉽게 서비스를 체험할 수 있도록 설계하였으며, IP 기반 제한을 통해 비회원 로그인 시스템 남용을 제한합니다.
사용자가 직접 제목, 케이스1, 케이스2, 타이머, 최소 금액을 설정할 수 있도록 구성되었고, 유효한 입력 값이 입력된 경우에만 방을 생성할 수 있습니다.
참여자는 소유한 코인의 일부를 원하는 옵션에 실시간으로 베팅할 수 있습니다. 서버와 클라이언트 간의 빠르고 안정적인 양방향 통신을 통해 실시간 데이터 업데이트와 사용자 간의 동기화를 제공합니다.
방에 참여한 모든 사용자가 실시간으로 채팅에 참여할 수 있도록 설계되었습니다. 안정적인 양방향 통신으로 메시지가 지연 없이 전달됩니다.
Redis의 List와 Pub/Sub을 활용하여 메시지 큐를 구현하였습니다.
List를 사용해 메시지의 순차적 처리를 보장하고, Pub/Sub을 통해 특정 시점에서 메시지를 소비할 수 있도록 합니다.
또한, ACK Timeout을 통해 처리되지 않은 메시지를 감지하고 재처리하는 로직을 구성하였습니다.
이 메시지 큐는 베팅 종료 후, 사용자들의 오리 코인 업데이트 작업을 처리하는 데 사용되었습니다.
베팅 종료 API의 성능 이슈로 인해 사용자 경험이 저하된다는 피드백을 받았습니다.
해당 API의 Redis 탐색 알고리즘을 개선하였습니다. 전체 키를 탐색하는 기존 방식 대신, 큐에 필요한 정보를 저장하여 즉시 반영할 수 있도록 하였습니다.
또한 메시지 큐를 이용하여, 비동기적으로 DB IO가 가능하도록 하였습니다.
결과적으로 API의 응답 시간이 75% 개선되었습니다.
시스템 성능 최적화와 데이터 일관성 유지의 균형을 위해 다양한 캐시 전략을 설계하고 구현했습니다.
프로젝트에서는 Read Through, Write Through, Write Back 등 여러 캐시 전략을 상황에 맞게 적용했습니다.
유저 정보 조회에는 Read Through를 사용해 빠른 응답 속도를 확보하고, 베팅 데이터 저장에는 Write Through를 적용해 데이터 정합성을 유지했으며, 실시간 베팅 정보 관리에는 Write Back을 활용해 쓰기 부하를 줄이면서 실시간성을 보장했습니다.
실시간 베팅 처리에서 Redis와 HINCRBY 명령어를 활용해 동시성 문제를 해결했습니다. Redis의 단일 스레드 기반 특성과 HINCRBY의 원자성을 활용해 데이터 업데이트 과정에서 발생할 수 있는 불일치를 방지했습니다. 이를 검증하기 위해 100만 번의 동시 요청을 처리하는 테스트를 진행하며 안정성을 확인했습니다.
Related Projects