在Redis中复制zset类型的数据

总结

我将排行榜数据等存储在Redis的zset中,想利用这些数据进行各种测试。
然而,尽管我试图寻找复制zset的方法,但未找到相关指令。很遗憾。

在这之中,找到了下面这个条目,写了一个简洁的脚本就可以复制的故事。
关于Redis的Lua脚本功能« Rest Term

在Redis中可以编写Lua脚本。

听说用EVAL命令可以写出来。

# 127.0.0.1:6379 にredis-serverがいるとして
redis-cli
127.0.0.1:6379> EVAL "return 'Hello, world!'" 0
#=> "Hello, world!"

读了这个,还可以收集参数。

127.0.0.1:6379> EVAL "return {KEYS[1], KEYS[2], ARGV[1], ARGV[2]}" 2 key1 key2 1 2
#=> 1) "key1"
#=> 2) "key2"
#=> 3) "1"
#=> 4) "2"

127.0.0.1:6379> EVAL "return {KEYS[1], KEYS[2], ARGV[1], ARGV[2]}" 2 key1 key2
#=> 1) "key1"
#=> 2) "key2"

127.0.0.1:6379> EVAL "return {KEYS[1], KEYS[2], ARGV[1], ARGV[2]}" 2 key1
#=> (error) ERR Number of keys can't be greater than number of args

可以使用SCRIPT LOAD命令将脚本注册。

如果使用SCRIPT LOAD和EVALSHA,各种事情都会变得更顺利。
(只要redis服务器没有崩溃,发出的哈希键应该还会保留)

127.0.0.1:6379> SCRIPT LOAD "return {KEYS[1], KEYS[2], ARGV[1], ARGV[2]}"
#=> "c0d2d6f81be75d67523d7c8ac69a932fbe1aa4e2"

127.0.0.1:6379> EVALSHA c0d2d6f81be75d67523d7c8ac69a932fbe1aa4e2 2 key1 key2
#=> 1) "key1"
#=> 2) "key2"

127.0.0.1:6379> exit
127.0.0.1:6379> EVALSHA c0d2d6f81be75d67523d7c8ac69a932fbe1aa4e2 2 key1 key2 1 2
#=> 1) "key1"
#=> 2) "key2"
#=> 3) "1"
#=> 4) "2"

复制zset的脚本

所以,我根据这些参考写了一份正题脚本。

暂时先制作一个原始数据的副本作为样本。

127.0.0.1:6379> ZADD key1 10 1
#=> (integer) 1
127.0.0.1:6379> ZADD key1 20 2
#=> (integer) 1
127.0.0.1:6379> ZADD key1 50 3
#=> (integer) 1
127.0.0.1:6379> ZADD key1 100 4
#=> (integer) 1
127.0.0.1:6379> ZADD key1 30 5
#=> (integer) 1
127.0.0.1:6379> ZADD key1 1 6
#=> (integer) 1

127.0.0.1:6379> ZRANGE key1 0 -1
#=> 1) "6"
#=> 2) "1"
#=> 3) "2"
#=> 4) "5"
#=> 5) "3"
#=> 6) "4"

所以,如果按照这样的方式运行脚本的话…

127.0.0.1:6379> EVAL "for i,v in ipairs(redis.call('zrange', KEYS[1], 0, -1)) do redis.call('zadd', KEYS[2], redis.call('zscore', KEYS[1], v), v) end" 2 key1 key2
#=> (nil)

127.0.0.1:6379> ZRANGE key2 0 -1
#=> 1) "6"
#=> 2) "1"
#=> 3) "2"
#=> 4) "5"
#=> 5) "3"
#=> 6) "4"

# ちゃんと`score`もコピーできてるで
127.0.0.1:6379> ZSCORE key2 6
#=> "1"
127.0.0.1:6379> ZSCORE key2 4
#=> "100"

感觉就是这样。很方便!

最后

可以用另一种语言编写脚本并执行,但是也可以随意执行,所以还是挺方便的。以上!

请参考

    • EVAL – Redis

 

    • RedisのLuaスクリプティング機能について « Rest Term

 

    Copy a redis sorted set to a set – Stack Overflow
bannerAds