매칭 알고리즘 ver 1
다소니의 매칭 알고리즘은 다음과 같이 구현하고자 하였습니다.
-
사용자가 매칭 요청을 했을 때
- 사용자의 레이팅과 성별에 따라 인원수가 3인 미만인 파티에 매칭
- 알맞은 파티가 없을 경우 파티를 새로 생성하여 해당 파티에 매칭
- 파티 인원이 3명이 되면, 상대 성별의 아직 매칭이 안된 파티중 파티 멤버의 평균 레이팅이 가장 근접한 파티를 찾습니다.
- 조건에 맞는 파티가 있을 경우 : 방을 생성하고 두 파티를 매칭시킵니다.
- 조건에 맞는 파티가 없을 경우 : 파티 대기열에 들어갑니다.
-
RDBMS에서 큐 정보를 관리였습니다.(기존 DB의 대략적인 ERD입니다)
-
유저 : 레이팅과 성별로 유저의 대기열을 구분합니다.
-
파티 멤버 : 파티와 유저의 중계 테이블입니다.
-
파티 : 방과 매칭하는 파티를 관리하기 위한 테이블입니다.
- 유저의 레이팅 및 성별에 따라 들어갈 수 있는 파티를 SELECT하게 됩니다.
-
방
- 방 유형 : 사설 방과 매칭 방으로 구분하기 위한 컬럼입니다.
[어려웠던 점]
- 과연 매칭 대기열을 RDBMS에서 관리하는 것이 맞나? 라는 생각이 들었습니다. 제가 자주 플레이하던 게임에서는 매칭을 돌리다가 게임 클라이언트를 끄면 해당 큐 정보는 사라져 있었고, 저 또한 이것이 당연한 로직이라는 생각이 들었습니다. 하지만 제가 구현한 방식대로 대기열을 관리할 경우, 최악의 경우에는 한번 요청한 대기열이 영구적으로 남아있을 가능성도 있다고 생각하였습니다.
- 서비스 내 방의 유형이 사설 방(유저가 직접 방을 생성하고 인원을 모집하는 방)과 매칭 방(매칭 알고리즘을 통해 생성된 방) 두 가지로 나뉘어져 있었습니다. 그런데 파티라는 개념은 오직 매칭 방을 위해 있는 테이블인데, 사설 방을 생성할 때에도 파티를 생성해줘야 하는 문제가 발생했습니다. 이로 인해 불필요한 코드가 늘어나고, 로직 또한 굉장히 복잡해졌습니다.
Redis를 사용하게 된 계기
다른 팀의 프로젝트 중간 발표에서 RabbitMQ를 활용해 일반 유저 매칭 큐와 특별 유저 매칭 큐를 구별해서 구현한 것을 보고, 기존의 방식이 잘못 되었다는 생각이 들어서 다른 방식을 찾아보게 되었습니다.