There are 10 sortedset leaderboards for many players, and each player picks there best 5 rank in this 10 leaderboards to get an average rank number.
Finally, rank all players by their best 5 average rank.
I notice that this average rank depends on other leaderboards and has no intuitive score. Calculating this avarage rank for every players for any change may be needed but cost too much?
Is there an effective redis way or any other technique could help?
CodePudding user response:
Calculating an average rank may indeed be too expensive.
Suppose that I'm down in the 10,000 range on a leaderboard. Then I win something and am in the 9000 range. You now have to look at 1000 other players, and recalculate their ranks, which involves looking at 10 leaderboards each and...well this is an unbounded amount of work.
You can do it with an embedded Lua script. But it will get slow.
Instead I'd suggest a lazy approach.
First create a function to recalculate someone's rank. Have all updates to the 10 leaderboards call that, so that a person who is active immediately sees their rank update.
Next, create a new sortedset of when to recalculate people. Something like your priority is now 100*sqrt(rank)
seconds. (Low is processed first.) So people at the top of the leaderboard get into the queue to come up fairly fast, but everyone gets processed regularly. Now you run a regular job that reprocesses part of the leaderboard.
This is a simple strategy that can be adjusted to achieve a good tradeoff between load on your system, and freshness. Without ever doing any long blocking operations.
For better freshness you can dedicate a read-only replica for use by a job to calculate what ranks should be, when then inserts back to the live data. Thereby allowing more frequent updates with less work for the rest of the system.