韶光繁芜度:取决于实行的脚本。

利用Lua脚本的好处:

减少网络开销。
可以将多个要求通过脚本的形式一次发送,减少网络时延。
原子操作。
redis会将全体脚本作为一个整体实行,中间不会被其他命令插入。
因此在编写脚本的过程中无需担心会涌现竞态条件,无需利用事务。
复用。
客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本而不须要利用代码完成相同的逻辑。

如何利用

phpluaredisRedis应用lua剧本 NoSQL

基本利用

命令格式:

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做区分。