韶光繁芜度:取决于实行的脚本。
利用Lua脚本的好处:
减少网络开销。可以将多个要求通过脚本的形式一次发送,减少网络时延。原子操作。redis会将全体脚本作为一个整体实行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会涌现竞态条件,无需利用事务。复用。客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本而不须要利用代码完成相同的逻辑。如何利用
基本利用
命令格式:
EVAL script numkeys key [key ...] arg [arg ...]
解释:
script是第一个参数,为Lua 5.1脚本。该脚本不须要定义Lua函数(也不应该)。第二个参数 numkeys指定后续参数有几个key。key[key...],是要操作的键,可以指定多个,在lua脚本中通过 KEYS[1], KEYS[2]获取arg[arg...],参数,在lua脚本中通过 ARGV[1], ARGV[2]获取。大略实例:
127.0.0.1:6379> eval \公众return ARGV[1]\公众 0 100 \公众100\"大众127.0.0.1:6379> eval \"大众return {ARGV[1],ARGV[2]}\"大众 0 100 1011) \"大众100\"大众2) \公众101\"大众127.0.0.1:6379> eval \"大众return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}\"大众 2 key1 key2 first second1) \"大众key1\"大众2) \"大众key2\"大众3) \"大众first\"大众4) \"大众second\"大众127.0.0.1:6379> eval \"大众redis.call('SET', KEYS[1], ARGV[1]);redis.call('EXPIRE', KEYS[1], ARGV[2]); return 1;\"大众 1 test 10 60(integer) 1127.0.0.1:6379> ttl test(integer) 59127.0.0.1:6379> get test\公众10\"大众
注:
{}在lua里是指数据类型 table,类似数组。redis.call()可以调用redis命令。命令行里利用
如果直策应用 redis-cli命令,格式会有点不一样:
redis-cli --eval lua_file key1 key2 , arg1 arg2 arg3
把稳的地方:
eval 后面参数是lua脚本文件, .lua后缀不用写 numkeys,而是利用 ,隔开。把稳 ,前后有空格。示例:
incrbymul.lua
local num = redis.call('GET', KEYS[1]); if not num then return 0;else local res = num ARGV[1]; redis.call('SET',KEYS[1], res); return res;end
命令走运行:
$ redis-cli --eval incrbymul.lua lua:incrbymul , 8(integer) 0$ redis-cli incr lua:incrbymul (integer) 1$ redis-cli --eval incrbymul.lua lua:incrbymul , 8(integer) 8$ redis-cli --eval incrbymul.lua lua:incrbymul , 8(integer) 64$ redis-cli --eval incrbymul.lua lua:incrbymul , 2(integer) 128
由于redis没有供应命令可以实现将一个数原子性的乘以N倍,这里我们就用Lua脚本实现了,运行过程中确保不会被其它客户端打断。
phpredis里利用
接着上面的例子:
incrbymul.php
<?php $lua = <<<EOFlocal num = redis.call('GET', KEYS[1]); if not num then return 0;else local res = num ARGV[1]; redis.call('SET',KEYS[1], res); return res;endEOF;$redis = new Redis();$redis->connect('127.0.0.1', 6379);$ret = $redis->eval($lua, array(\"大众lua:incrbymul\"大众, 2), 1);echo $ret;
运行:
$ redis-cli set lua:incrbymul 0OK$ redis-cli incr lua:incrbymul(integer) 1$ php incrbymul.php 2$ php incrbymul.php 4
eval原型:
Redis::eval(string script, [array keys, long num_keys])
eval函数的第3个参数为KEYS个数,phpredis依据此值将KEYS和ARGV做区分。