1、直接使用EVAL执行,不算在“更好”的范围内,不做讨论。
2、正常判断式:先判断脚本存不存在,再进行操作。
/** * 向Redis注册Lua脚本 * * @param Redis $redis * @param $file * * @return bool|mixed|string */ function load_lua_script(Redis $redis, $file) { if (!is_file($file)) { return false; } $sha1 = sha1_file($file); if ($redis->script('EXISTS', $sha1)[0] == 1) { return $sha1; } else { return $redis->script('LOAD', file_get_contents($file)); } } $script_sha = load_lua_script($redis, '/path/to/lua_script.lua'); $reuslt = $redis->evalSha($script_sha, $args, $key_number);
3、触发式执行:如果执行失败了,才LOAD脚本,并重新运行。
/** * 执行Lua脚本 * * @param Redis $redis * @param $file * @param $args * @param $numKeys * * @return bool|mixed|string */ function run_lua_script(Redis $redis, $file, $args, $numKeys) { if (!is_file($file)) { return false; } $sha1 = sha1_file($file); for ($run_number = 0; $run_number < 3; $run_number++) { $redis_result = $redis->evalSha($sha1, $args, $numKeys); // 检测脚本是否不存在,如果不存在,则加载,并重新执行 if (substr($redis->getLastError(), 0, 8) === 'NOSCRIPT') { echo 'LOAD' . PHP_EOL; $sha1 = $redis->script('LOAD', file_get_contents($file)); $redis->clearLastError(); continue; } return $redis_result; } return false; } $reuslt = run_lua_script($redis, '/path/to/lua_script.lua', $args, $key_number);
测试:
Lua脚本:
-- lua_script.lua local value = redis.call('INCRBY', KEYS[1], ARGV[1]) return 'hello ' .. value
二号脚本测试运行10000次:8万次单程 IO 运行 0.9738 秒。
三号脚本测试运行10000次:4万次单程 IO 运行 0.6284 秒。
显而易见,触发式脚本可以更好的节约IO、以高的性能运行。