PHP中用redis运行lua插件和multi和pipeline相当
原创<?php
//$redis = new Redis(); #实例化redis类
$redis->connect(127.0.0.1); #连接服务器
$lua = <<<SCRIPT
return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}
SCRIPT;
//对应的redis命令如下 eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
$s = $redis->eval($lua,array(key1,key2,first,second),2);
var_dump($s);
//解锁
$redis->del(lockkey);
$redis->set(lockkey,123);
$lock=[key=>lockkey,token=>123];
var_dump(unlock($redis,$lock));
//批量获取hash的值
$redis->del(user:1,user:2,errKey);
$redis->hmset(user:1,["age"=>21,"name"=>"jack"]);
$redis->hset("user:2","age","22");
$redis->hset("user:2","name","tom");
$pipe = $redis->multi(Redis::PIPELINE);
$pipe->hgetAll(user:1);
$pipe->lpop(errKey);
$pipe->set(a,100);
$pipe->hgetAll(user:2);
$pipeResult = $pipe->exec();
var_dump(PJPELINE----,$pipeResult);
var_dump($redis->get(a));
$pipe = $redis->multi(Redis::MULTI);
$pipe->hgetAll(user:1);
$pipe->lpop(errKey);
$pipe->set(a,200);
$pipe->hgetAll(user:2);
$pipeResult = $pipe->exec();
var_dump(MULTI----,$pipeResult);
var_dump($redis->get(a));
$script="local rst={}; for i,v in pairs(KEYS) do rst[i]=redis.call(hgetall, v) end; return rst";
var_dump(LUA----,$redis->eval($script,[user:1,user:2],2));
$redis->close(); #关闭连接
function unlock($redis,array $lock)
{
$key = $lock[key];
$token = $lock[token];
$script =
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
else
return 0
end
;
return $redis->eval($script, [$key, $token], 1);
}
说明:
lua
$redis->eval($lua,array(key1,key2,first,second),2)执行的对应命令如下:
eval “return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}” 2 key1 key2 first second
解释: “return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}” 是被求值的 Lua 脚本,数字 2 指定了键名参数的数量, key1 和 key2 是键名参数,分别使用 KEYS[1] 和 KEYS[2] 访问,而最后的 first 和 second 则是附加参数,可以通过 ARGV[1] 和 ARGV[2] 访问它们。
PHP中使用redis拓展执行脚本时,eval方法的参数 3个,第一个是脚本代码,第二个是一个数组,参数数组,第三个参数是个整数,表示第二个参数中的前几个键名参数,剩下的都是附加参数
multi与pipeline流水线
Redis::MULTI方式会将命令逐条发给redis服务端,服务端缓冲。只有在需要使用事务时才选择Redis::MULTI方式,它可以保证发给redis的一系列命令以原子方式执行。但效率相应也是最低的。(不如连续发送多个执行快)
交互过程:tcpdump -i any port 6480 -A
$5
MULTI
OK
$3
GET
$1
a
QUEUED
$3
GET
$1
a
QUEUED
EXEC
$3
bbb
$3
bbb
Redis::PIPELINE方式,可以将一系列命令打包发给redis服务端,客户端缓冲,不保证这些命令原子执行。如果只是为了一下执行多条redis命令,无需事务和原子性,那么应该选用Redis::PIPELINE方式。代码的性能会有大幅度提升!
$3
GET
$1
a
*2
$3
GET
$1
a
$3
bbb
$3
bbb
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除