信息资讯综合思念体

【PHP】Redis 中如何更好的加载Lua脚本

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、以高的性能运行。


«   2020年4月   »
12345
6789101112
13141516171819
20212223242526
27282930
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接
  • RainbowSoft Studio Z-Blog
  • 订阅本站的 RSS 2.0 新闻聚合

Powered By Z-BlogPHP 1.5.1 Zero Theme By 爱墙纸

百度资讯综合思念体对有机生命接触用人形终端界面 那就是
晋ICP备15000230号-1