-1

Let's say we want to design a gaming platform for chess and our userbase is ~50M. And whenever a player comes to our platform to play chess we assign a random player with almost the same rating as an opponent. Every player has 4 level rating [Easy, Medium, Hard, Expert].

My approach was to keep all user in Redis cache(assume all users/boats are live and waiting for the opponent) so we are keeping data in the below format:

"chess:easy" : [u1, u2, u3]
"chess:medium" : [u4, u5, u6]

so when a user comes I will remove a user from the cache and assign.

For example: u7 (easy) wants to play chess games then his opponent will be u1(easy).

But won't this create a problem for concurrent requests as we read then remove from Redis List that will be blocking?

Can anyone suggest a better approach with or without cache?

Noob
  • 174
  • 1
  • 2
  • 19

1 Answers1

1

But won't this create a problem for concurrent requests as we read then remove from Redis List that will be blocking?

No, because Redis is single-threaded when it performs write but, assuming the 50M users are equality distributed across the chess level, you would get 4 lists, one per difficulty, with a length of 12,5 million

Manipulating the list could have a lot of complexity because using [LPOP][1] to select a user and remove it has O(N) complexity and the last user may wait a lot of time before getting an opponent.

I think you should aim to use a HASH data structure and splitting the users in different databases:

  • db0: Easy
  • db1: Medium
  • db2: Hard
  • db3: Expert

In this way, you can store the users that want to play with HSET <USERID> status "ready to play" and then benefit the RANDOMKEY command to select an opponent and delete it with HDEL <KEY RETURNED BY RANDOM> status.

Doing so, you will execute commands O(1) only, providing a fast and reliable matching system that you can optimize further with the redis pipeling feature.

NB: if you set and hash per difficulty level and adding multiple fields to the hash, you will hit the O(N) complexity due to the HDEL command! [1]: https://redis.io/commands/lpop

Can anyone suggest a better approach with or without cache?

There are many algorithms you may use such as:

but it depends on the user experience you want to implement for your clients. You can explore the gamedev.stackexchange.com community

Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73