How to store in Redis sorted set with server-side timestamp as score?

前端 未结 1 649
甜味超标
甜味超标 2020-12-21 18:45

I want to use a sorted set to store objects using the redis-server timestamp as score.

I know I can use Redis Streams with * id, but Redis Streams have

相关标签:
1条回答
  • 2020-12-21 19:22

    The solution is to use a Lua script:

    local time = redis.call('TIME')
    local ts = time[1]..string.format('%06d', time[2])
    return redis.call('ZADD', KEYS[1], ts, ARGV[1])
    

    Here we use Redis TIME command. The command returns:

    • unix time in seconds
    • microseconds

    So we can concatenate these two and use a microsecond-timestamp. We need to zero-pad the microseconds part.

    Since sorted sets are good with integer values up to 2^53, our timestamp is safe all the way up to the year 2255.

    This is Redis-Cluster-safe as we store in one key. To use multiple keys, make sure to land them on the same node using hash tags if you want to compare timestamps.

    You can modify the script to use lower than microsecond resolution.

    Here the EVAL command, simple pass key and value as arguments, no need to create the sorted set before hand:

    EVAL "local time = redis.call('TIME') local ts = time[1]..string.format('%06d', time[2]) return redis.call('ZADD', KEYS[1], ts, ARGV[1])" 1 ssetKey myVal
    

    As always, you may want to load the script and use EVALSHA.

    > SCRIPT LOAD "local time = redis.call('TIME') local ts = time[1]..string.format('%06d', time[2]) return redis.call('ZADD', KEYS[1], ts, ARGV[1])"
    "81e366e422d0b09c9b395b5dfe03c03c3b7b3bf7"
    > EVALSHA 81e366e422d0b09c9b395b5dfe03c03c3b7b3bf7 1 ssetKey myNewVal
    (integer) 1
    

    A note on Redis version. If you are using:

    • Redis Version before 3.2: sorry, you cannot use TIME (non-deterministic command) and then write with ZADD.
    • Redis Version greater than 3.2 but < 5.0: Add redis.replicate_commands() on top of the script. See Scripts as pure functions
    • Redis 5.0 an up: you are good.
    0 讨论(0)
提交回复
热议问题