David Gourde
David Gourde

Reputation: 3914

Redis sorted set based on score and date time as tie breaker?

I would like to use a redis' sorted set as a leader board. But using ZREVRANGE 0 x, I can only get the top x from the score (the end of the score based ascending sorted set), with the default tie breaker which is, from the official redis documentation:

Lexicographical order is used for elements with equal score.

The tie breaker I would need is the date time of the score entry.

e.g.

submits (in order)     redis sorts it as      I need
User1 -- Score 50      User1                  User1
User3 -- Score 40      User2                  User3
User2 -- Score 40      User3                  User2

The only solution I see is to store the date time of the last update on the entry but still use ZREVRANGE key 0 x to get max and min scores from the the top x users. Then do a ZREVRANGEBYSCORE key max min. If the result length is higher than x, there is at least one tie so I would sort that smaller list in Lua using 2 keys.

This method seems very slow and I need to make it work for hundreds of thousands of users. I don't like the 2 calls and processing with Lua (on the redis side, to stay atomic) and would like to know if there is a better way to use 2 keys for sorted sets or configure another tie breaker?

My code is already written so I cannot change my type of database. If you have any interesting idea, I am interested to hear them, as I am not an expert about redis.

Upvotes: 2

Views: 4622

Answers (1)

DhruvPathak
DhruvPathak

Reputation: 43235

The sorted set score is a floating point value. Your score and datetime of the score can both fit into that.

  1. The score would be an integer in some range, say 0 to 2^10, will need 10 bits only
  2. The score can be unix timestamp seconds since Jan'2010 ( to reduce the size of the timestamp, for simplicity you can even take simple unix timestamp as integer)

Now lets call the redis score as RScore. You can put the person's score in leftmost 10 bits of the number, and timestamp in rightmost x bits. The bits in middle can be zero.

So, whenever you sort Rscore, it will be first sorted by score, and if there is a tie, it will be sorted by unix timestamp present in the right bits. To find the score and timestamp of the score from RScore, you just have to parse the right set of bits. An example utility which does this in python is here.

Upvotes: 8

Related Questions