您现在的位置是:主页 > news > 手机网站课程/策划网络营销方案

手机网站课程/策划网络营销方案

admin2025/5/21 14:12:02news

简介手机网站课程,策划网络营销方案,四川建设网网,建设企业网站地址Redis从2.6版本开始内置了一个lua脚本解释器,这让Redis在一定程度上成为一门可编程的数据库,如同Oracle的pl/sql,下面简单介绍下该特性 Redis执行lua脚本主要依靠两个命令:EVAL和EVALSHA EVAL 和 EVALSHA 命令是从 Redis 2.6.0 版本开始的&a…

手机网站课程,策划网络营销方案,四川建设网网,建设企业网站地址Redis从2.6版本开始内置了一个lua脚本解释器,这让Redis在一定程度上成为一门可编程的数据库,如同Oracle的pl/sql,下面简单介绍下该特性 Redis执行lua脚本主要依靠两个命令:EVAL和EVALSHA EVAL 和 EVALSHA 命令是从 Redis 2.6.0 版本开始的&a…

Redis从2.6版本开始内置了一个lua脚本解释器,这让Redis在一定程度上成为一门可编程的数据库,如同Oracle的pl/sql,下面简单介绍下该特性

Redis执行lua脚本主要依靠两个命令:EVAL和EVALSHA


EVAL 和 EVALSHA 命令是从 Redis 2.6.0 版本开始的,使用内置的 Lua 解释器,可以执行 Lua 脚本。

EVAL 命令要求你在每次执行脚本的时候都发送一次脚本主体(script body)。Redis 有一个内部的缓存机制,因此它不会每次都重新编译脚本,不过在很多场合,付出无谓的带宽来传送脚本主体并不是最佳选择。

为了减少带宽的消耗, Redis 实现了 EVALSHA 命令,它的作用和 EVAL 一样,都用于对脚本求值,但它接受的第一个参数不是脚本,而是脚本的 SHA1 散列值。


EVAL的第一个参数是一段 Lua 5.1 脚本程序。 这段Lua脚本不需要(也不应该)定义函数。它运行在 Redis 服务器中。

EVAL的第二个参数是参数的个数,后面的参数(从第三个参数),表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。

在命令的最后,那些不是键名参数的附加参数 arg [arg …] ,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,以此类推)。

Redis在lua脚本中提供了两个方法用来执行任意Redis命令:redis.call()和redis.pcall(),两者的区别是出错时前者直接报错,后者会捕获错误并返回错误信息

127.0.0.1:6379> EVAL 'return redis.call("set", KEYS[1], ARGV[1])' 1 name dog
OK
127.0.0.1:6379> get name
"dog"
127.0.0.1:6379> EVAL 'return redis.pcall("get", KEYS[1])' 1 name
"dog"
127.0.0.1:6379> 

Redis中lua脚本的应用场景:

就目前来看,通过EVAL命令和redis.call()方法可以执行任意redis命令,就给我们带来了便利,如果我们当前使用的redis客户端(比如php扩展)版本较低或是没有实现某些命令,lua脚本就派上用处了(当然php还可以使用Redis扩展中提供的rawCommand方法来执行任何原生命令,这里只是方便介绍),以下是php利用EVAL操作hyperloglogs代码演示

<?php$redis = new Redis();
$redis->connect("127.0.0.1");var_dump($redis->eval('return redis.call("pfadd", KEYS[1], "a", "b", "c")', array('hhl'), 1)); //执行pfadd命令$redis->rawCommand('pfadd', 'hhl', 'c', 'd', 'e');  //同样可以执行pfadd命令var_dump($redis->pfcount('hhl'));
var_dump($redis->eval('return redis.call("pfcount", KEYS[1])', array('hhl'), 1));  //采用lua脚本方式执行pfcount命令$script = 'return redis.call("pfadd", KEYS[1], KEYS[2])';$sha1 = $redis->script('load', $script);  //让redis服务器缓存该脚本并返回脚本的sha1散列值echo "sha1: $sha1" . PHP_EOL;for($i = 0; $i < 1000; $i++)
{$redis->rawCommand('evalsha', $sha1, 2, 'h1', md5($i)); //使用evalsha重复执行脚本,每次pfadd $i的md5值
}var_dump($redis->pfcount('h1'));$redis->close();

执行结果:

int(1)
int(5)
int(5)
sha1: 7b7ad98b87e3eea9e0f07b18f6f0e63c54ea8b32
int(1003)  //添加了1000个元素,统计却返回了1003,因为hyperloglogs的特性决定了统计不是完全精确,存在一定误差。

That's it!