Redis的「zMScore」操作

背景

最近在做公司项目时遇到这样一个场景:
需要从Redis有序集合中取出20个元素,并且附带对应的score。
因为有mGethMGet等方便的指令,我下意识地在键盘上输入zMScore,可奈何phpredis扩展中不带有这儿方法,查阅资料之后,发现Redis本生就不带有这个方法。

问题

背景所述的Redis操作时放在接口中的,采用for循环用zScore操作必然会加大程序和Redis的数据交互次数,导致接口速度变慢。

思考

1、类似于MySQL,Redis也是支持事务的,利用multiexec操作将20个zScore包起来;
2、编写Lua脚本,利用eval方法进行操作;

实践

代码

  • for循环方式
<?php
$redis = new \Redis();
$redis->connect('127.0.0.1', '6379');
$result = array();
$timeBegin = microtime(true);
for($i = 0; $i < 20; $i++) {
    $key = 'test' . $i;
    $result[$key] = (int)$redis->zScore('testSSet', $key);
}
$timeEnd = microtime(true);
var_dump($timeEnd - $timeBegin);
  • 事务方式
<?php
$redis = new \Redis();
$redis->connect('127.0.0.1', '6379');
$result = array();
$timeBegin = microtime(true);
$redis->multi();
for($i = 0; $i < 20; $i++) {
    $key = 'test' . $i;
    $redis->zScore('testSSet', $key);
}
$result = $redis->exec();
$timeEnd = microtime(true);
var_dump($timeEnd - $timeBegin);
  • eval方式
<?php
$redis = new \Redis();
$redis->connect('127.0.0.1', '6379');
$script = "return {%s}";
$keys = array();
$strs = array();
$timeBegin = microtime(true);
for($i = 0; $i < 20; $i++) {
    $index = $i + 1;
    $key = 'test' . $i;
    $keys[] = $key;
    $strs[] = "KEYS[{$index}]";
    $strs[] = "redis.call('zScore', 'testSSet', KEYS[{$index}])";
}
$script = sprintf($script, implode(',', $strs));
$result = $redis->eval($script, $keys, 20);
$timeEnd = microtime(true);
var_dump($timeEnd - $timeBegin);

结果

  • for循环方式:关键部分的耗时平均在0.6ms;
  • 事务方式:关键部分的耗时平均在0.6ms;
  • eval方式:关键部分的耗时平均在0.2ms;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。