//https://www.cnblogs.com/taijun/p/5007329.html
$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);
}
$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个,第一个是脚本代码,第二个是一个数组,参数数组,第三个参数是个整数,表示第二个参数中的前几个键名参数,剩下的都是附加参数
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
redis批量获取hash key的数据
PHP中使用redis执行lua脚本示例
redis中multi与pipeline介绍分析
在 Linux 命令行中使用 tcpdump 抓包