在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