10장 실시간 게임 순위표
Opened this issue · 2 comments
HaeUlNam commented
10장 실시간 게임 순위표
minkukjo commented
끄적끄적
- 실시간 게임 순위표 만들기
- 게임 서비스에서 게임 결과를 순위표 서비스에 갱신 요청을 보내고 순위표 저장소는 이를 저장
- 흥미로운 부분은 카프카를 도입할 때, 게임 점수를 다른 서비스에서도 사용해야한다면 메시지 큐를 도입하지만, 그렇지 않다면 도입하지 않는 다는 부분이 인상깊었음 (오버엔지니어링 지양?)
- DB 보다는 레디스의 sortedSet 같은 기능을 사용해서 순위를 측정하는 것이 좋다고 함
- 더 빠르게 검색하기 위해 색인 리스트를 둬서 마치 바이너리 서치나 B-Tree처럼 구간을 뛰어넘어서 조회할 수 있도록 하는 방법도 있음
- 여기서는 특이하게 클라우드 서비스를 이용하는 방법과 자체 서비스를 이용하는 방안이 나온다.
- 다만 개인적으로는 클라우드 서비스를 쓸지, 자체 서비스를 쓸지를 결정하는 가장 큰 기준은 결국
비용
이 아닐까 싶다.- 클라우드 비용이 부담스러운 팀이라면 자체 서비스를 구축하겠지만, 자체 서비스를 구축/운영/모니터링 하는 것 또한 비용이기 때문에 어떤 부분에 더 무게를 둘지는 사실 개발자 개인의 판단 보다는 CEO나 CTO의 역량이지 않나 싶기도 함
- 레디스 규모 확장을 위해 고정 파티션과 해시 파티션 두 가지 방법이 나온다.
- 고정 파티션은 말 그대로 범위별로 데이터 크기를 나눠서 저장하는 방식, 샤드에 범위별로 나눠서 저장한다고 보면 된다.
- 해시 파티션은 특정 점수대의 유저가 몰려있는 경우에 쓰면 좋은데, 이 때 해시슬롯을 사용하면 균등하게 분배해볼 수 있다.
- 레디스의 대안으로 NoSQL도 나오긴 했는데, 뭔가 구현하는걸 보니까 레디스 대비 굉장히 복잡해보이긴 해서 순위를 결정지을 때는 레디스가 가장 괜찮은 대안이 아닌가 싶기도 함.
HaeUlNam commented
-
P344에 GET /v1/scores라는 API를 만들던데, parameter를 열어둘 거 아니면 차라리 top10player처럼 명시적인 걸 naming에 넣으면 어떤가 생각했음
-
Man-in-the-Middle-attack 공격과 같은 보안 이슈가 발생할 수 있기에 클라이언트가 점수를 정하는 방식은 좋지 않음
-
아래 그림에서 2, 3의 점수 갱신은 메세징으로 쓴다면 장애 대응에 좋지 않을까? 책에서는 기능의 확장성에 대해서만 이야기하는 것 같아서..
-
점수에 index를 거는 게 할 수 있는 최적화라고 할 수 있을까? User별로 점수가 겹치는 경우가 많다면 index 성능이 좋지 않을 수도..? 현재로서 할 수 있는 최선일 수도 있을 것 같다.
-
레디스 사용
- 메모리 기반 Key-value
- Sorted set: Hash table + Skip list. Skip list는 정렬된 연결 리스트에 다단계 색인을 두는 구조. 그냥 정렬된 연결리스트는 삽입, 삭제, 검색 연산이 O(n)이지만, 스킵 리스트는 O(log(n))
-
해시 파티션의 문제점: 특정 사용자의 순위를 결정할 간단한 방법이 없다. 점수에 따른 고정 파티션.
- 하지만 점수 범위에 따른 고정 파티션을 쓴다면 핫스팟이 생길 것 같다.
-
Nosql: 쓰기 연산에 최적화되어있거나 같은 파티션 내의 항목을 점수에 따라 효율적으로 정렬 가능한 데이터베이스가 이상적. DynamoDB, Cassandra, MongoDB 등이 있다.
- DynamoDB는 index도 제공해준다.
- 핫 파티션을 피하기 위해서는 데이터를 n개 파티션으로 분할하고 파티션 번호를 파티션 키에 추가하는 것. 읽기와 쓰기 사이의 트레이드 오프가 있을 수 있음. 데이터를 분할하면 특정 파티션이 받는 부하는 줄어들겠지만, 읽기 구현은 어려워진다.