使用lua 脚本操作redis可减少与redis数据的连接次数,减少网络传输带来的时间浪费。在某些情景下,当我们需要对redis进行一系列的操作时我们可以使用lua。下面给出简单的示例。
redis-cli 运行lua 脚本
redis-cli -h host -p port -a password -n db –eval demo.lua k1 k2 , a1 a2
连接远程redis 并运行当前文件夹下的test.lua脚本。其中,-n 后接的参数为选择的redis db。 后面“k1 k2 , a1 a2” 的在lua 脚本中获取的方式是使用全局变量 KEYS 和 ARGV。
如果连接本地的redis运行脚本则可省略几个参数
redis-cli -n db –eval demo.lua k1 k2 , a1 a2
redis客户端命令行模式下运行lua脚本,使用eval 命令。如:
121.8.164.91:6383> eval “return {KEYS[1], KEYS[2], ARGV[1], ARGV[2]}”
注意需要获取返回数据必须使用 return
PHP 连接redis运行lua
$lua = 'return KEYS[1]';
// 也可以使用 file_get_contents() 读取lua脚本内容
// $lua = file_get_contents('/tmp/demo.lua');
$data = new \Redis()->connect('192.168.0.1', '6383')->auth('123456')->select(2)->eval($lua ,['k1', 'k2','a1', 'a2'], 2);
lua 操作redis
lua 操作redis比较简单,使用 redis.call(
order,
o
r
d
e
r
,
argv1, $argv2…);
将redis使用命令行时的参数依次作为参数传入,即可。
如:
- 使用获取指定key的值
redis.call(‘GET’,’key_demo’);
求多个zSet的并集,并存储为union_set。的
redis.call(‘ZUNIONSTORE’, ‘union_set’, ‘zSet_1’, ‘zSet_2’, ‘zSet_3’);
统计一个zSet中的元素个数
redis.call(‘ZCARD’,’union_set’);
lua脚本示例
- 统计union_set中元素个数
-- 注释,统计union_set中元素个数。如果大于10,则给zSetCountDes赋值'more then 10 ', 如果小于10,则给zSetCountDes赋值'less then 10'
local zSetCount = '';
local zSetCountDes = '';
zSetCount = redis.call('ZCARD','union_set');
if (zSetCount>10)
then
zSetCountDes = 'more then 10';
else
zSetCountDes = 'less then 10';
end;
return zSetCountDes;
- 遍历zSet中元素
local value = '';
local score = '';
local responseJson = '';
local zSetElement = redis.call('ZRANGE', 'zSet_1',0, 1, 'WITHSCORES');
for key,val in pairs(zSetElement) do
paidCountKey = gameId .. '_' .. 'activation_paid_count';
moneyCountKey = gameId .. '_' .. 'activation_paid_money_count';
-- 奇数key 对应val是 value
-- 偶数key 对应val是 score
if (key%2==1)
then
value = val;
else
score = val;
end;
responseJson = responseJson .. value .. ':' .. score .. ',';
end;
-- 拼接成json字符串
responseJson = '{' .. string.sub(responseJson, 1, -2) .. '}';
return responseJson;
如果zSet_1中数据为:
1) "value_a"
2) "score_a"
3) "value_b"
4) "score_b"
则脚本返回的字符串为:”{\”value_a\”:\”score_a\”, \”value_b\”:\”score_b\”}
注意使用 redis.call(‘ZRANGE’, ‘zSet_1’,0, 1, ‘WITHSCORES’);获取zSet中数据时是table类型。此时奇数key 对应val 才是zSet中value 而紧接着的一个偶数key对应的 val 才是value对应的score值。
如使用命令:
121.8.164.91:6383> zrange zSet_1 0 1 withscores
可看到如下数据:
1) "value_a"
2) "score_a"
3) "value_b"
4) "score_b"
则在lua中使用for key,val in pairs(zSetElement) do … end; 遍历时key和val 会是这样:
key val
1 "value_a"
2 "score_a"
3 "value_b"
4 "score_b"