$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('PIPELINE-----', $pipeResult);
var_dump($result->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 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的一系列命令以原子方式执行。但效率相应也是最低的。(不如连续发送多个执行快)
Redis::PIPELINE
方式,可以将一系列命令打包发给redis服务端,客户端缓冲,不保证这些命令原子执行。如果只是为了一下执行多条redis命令,无需事务和原子性,那么应该选用Redis::PIPELINE
方式。代码的性能会有大幅度提升!