平时你用 Redis 是不是经常 get()、set()一把梭?其实 Redis 中还有很多有用的数据结构,以及各种方法。今天我们就来测试一下eval()方法。
推荐:《Redis视频教程》
Redis Eval 官方说明(节选)
EVAL script numkeys key [key ...] arg [arg ...]
从 Redis 2.6.0 版本开始,通过内置的 Lua 解释器,可以使用 EVAL 命令对 Lua 脚本进行求值。
Redis 使用单个 Lua 解释器去运行所有脚本,并且, Redis 也保证脚本会以原子性(atomic)的方式执行:当某个脚本正在运行的时候,不会有其他脚本或 Redis 命令被执行。这和使用 MULTI / EXEC 包围的事务很类似。在其他别的客户端看来,脚本的效果(effect)要么是不可见的(not visible),要么就是已完成的(already completed)。
另一方面,这也意味着,执行一个运行缓慢的脚本并不是一个好主意。写一个跑得很快很顺溜的脚本并不难,因为脚本的运行开销(overhead)非常少,但是当你不得不使用一些跑得比较慢的脚本时,请小心,因为当这些蜗牛脚本在慢吞吞地运行的时候,其他客户端会因为服务器正忙而无法执行命令。
实测
我的理解,Redis 中的 eval() 方法一般用于需要执行多个 redis 操作,来完成一个目标的场景。
下面我模拟了一个操作 100 次 redis 的场景,当然实际可能并不需要这么多,仅仅想让大家看到差别。
<?php $redis = new \Redis; $redis->connect('127.0.0.1', 6379); // 清空Redis $redis->flushDB(); // PHP 中循环 set $t = microtime(true); for($i = 0; $i < 100; ++$i) { $redis->set('key' . $i, $i); } echo 'php for set: ', microtime(true) - $t, PHP_EOL; // 清空Redis $redis->flushDB(); // 使用 eval 方法 $t = microtime(true); $keys = []; $values = []; for($i = 0; $i < 100; ++$i) { $keys[] = 'key' . $i; $values[] = $i; } $redis->eval(<<<SCRIPT for i=1,#KEYS do redis.call('set', KEYS[i], ARGV[i]) end SCRIPT , array_merge($keys, $values), count($keys)); echo 'eval:', microtime(true) - $t, PHP_EOL;
结果:
php for set: 0.056596040725708 eval:0.00089216232299805
显而易见,eval碾压性地,比在代码中循环set来的快。
……
你以为这就完了?
不!
evalSha了解一下?
EvalSha 说明
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
根据给定的 sha1 校验码,对缓存在服务器中的脚本进行求值。
将脚本缓存到服务器的操作可以通过 SCRIPT LOAD 命令进行。
这个命令的其他地方,比如参数的传入方式,都和 EVAL 命令一样。
EvalSha 实测
<?php function testEval($redis) { $keys = []; $values = []; for($i = 0; $i < 100; ++$i) { $keys[] = 'key' . $i; $values[] = $i; } $redis->eval(<<<SCRIPT for i=1,#KEYS do redis.call('set', KEYS[i], ARGV[i]) end SCRIPT , array_merge($keys, $values), count($keys)); } function testEvalSha($redis) { $keys = []; $values = []; for($i = 0; $i < 100; ++$i) { $keys[] = 'key' . $i; $values[] = $i; } $redis->evalSha(sha1(<<<SCRIPT for i=1,#KEYS do redis.call('set', KEYS[i], ARGV[i]) end SCRIPT ), array_merge($keys, $values), count($keys)); } $redis = new \Redis; $redis->connect('127.0.0.1', 6379); // 清空Redis $redis->flushDB(); // 使用 eval 方法 $t = microtime(true); for($i = 0; $i < 100; ++$i) { testEval($redis); } echo 'eval:', microtime(true) - $t, PHP_EOL; // 清空Redis $redis->flushDB(); // 使用 evalSha 方法 $t = microtime(true); for($i = 0; $i < 100; ++$i) { testEvalSha($redis); } echo 'evalSha:', microtime(true) - $t, PHP_EOL;
结果:
eval:0.081475973129272 evalSha:0.076005220413208
从我测试的结果来看,evalSha的速度并不比eval有显著的提升。
但是,在生产环境下,如果使用evalSha会比eval发送更小的数据包,占用更少的网络资源。
因为eval每次都需要把脚本完整发送给redis,而evalSha只需要传递一个sha1即可。
当执行过一次eval后,evalSha 才可以直接调用。
福利
下面是我封装的一个方法,优先使用 evalSha 尝试,失败则使用 eval 方法。
/** * eval扩展方法,结合了 eval、evalSha * * 优先使用 evalSha 尝试,失败则使用 eval 方法 * * @param \Redis $redis * @param string $script * @param array $args * @param int $num_keys * @return mixed */ function evalEx($redis, $script, $args = null, $num_keys = null) { $sha1 = sha1($script); $redis->clearLastError(); $result = $redis->evalSha($sha1, $args, $num_keys); if('NOSCRIPT No matching script. Please use EVAL.' === $redis->getLastError()) { $result = $redis->eval($script, $args, $num_keys); } return $result; }
以上是Redis->eval() 到底好在哪?的详细内容。更多信息请关注PHP中文网其他相关文章!

Redis与其他数据库相比,具有以下独特优势:1)速度极快,读写操作通常在微秒级别;2)支持丰富的数据结构和操作;3)灵活的使用场景,如缓存、计数器和发布订阅。选择Redis还是其他数据库需根据具体需求和场景,Redis在高性能、低延迟应用中表现出色。

Redis在数据存储和管理中扮演着关键角色,通过其多种数据结构和持久化机制成为现代应用的核心。1)Redis支持字符串、列表、集合、有序集合和哈希表等数据结构,适用于缓存和复杂业务逻辑。2)通过RDB和AOF两种持久化方式,Redis确保数据的可靠存储和快速恢复。

Redis是一种NoSQL数据库,适用于大规模数据的高效存储和访问。1.Redis是开源的内存数据结构存储系统,支持多种数据结构。2.它提供极快的读写速度,适合缓存、会话管理等。3.Redis支持持久化,通过RDB和AOF方式确保数据安全。4.使用示例包括基本的键值对操作和高级的集合去重功能。5.常见错误包括连接问题、数据类型不匹配和内存溢出,需注意调试。6.性能优化建议包括选择合适的数据结构和设置内存淘汰策略。

Redis在现实世界中的应用包括:1.作为缓存系统加速数据库查询,2.存储Web应用的会话数据,3.实现实时排行榜,4.作为消息队列简化消息传递。Redis的多功能性和高性能使其在这些场景中大放异彩。

Redis脱颖而出是因为其高速、多功能性和丰富的数据结构。1)Redis支持字符串、列表、集合、散列和有序集合等数据结构。2)它通过内存存储数据,支持RDB和AOF持久化。3)从Redis6.0开始引入多线程处理I/O操作,提升了高并发场景下的性能。

RedisisclassifiedasaNoSQLdatabasebecauseitusesakey-valuedatamodelinsteadofthetraditionalrelationaldatabasemodel.Itoffersspeedandflexibility,makingitidealforreal-timeapplicationsandcaching,butitmaynotbesuitableforscenariosrequiringstrictdataintegrityo

Redis通过缓存数据、实现分布式锁和数据持久化来提升应用性能和可扩展性。1)缓存数据:使用Redis缓存频繁访问的数据,提高数据访问速度。2)分布式锁:利用Redis实现分布式锁,确保在分布式环境中操作的安全性。3)数据持久化:通过RDB和AOF机制保证数据安全性,防止数据丢失。

Redis的数据模型和结构包括五种主要类型:1.字符串(String):用于存储文本或二进制数据,支持原子操作。2.列表(List):有序元素集合,适合队列和堆栈。3.集合(Set):无序唯一元素集合,支持集合运算。4.有序集合(SortedSet):带分数的唯一元素集合,适用于排行榜。5.哈希表(Hash):键值对集合,适合存储对象。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

Atom编辑器mac版下载
最流行的的开源编辑器

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

SublimeText3汉化版
中文版,非常好用

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)