背景
最近在做公司項(xiàng)目時(shí)遇到這樣一個(gè)場(chǎng)景:
需要從Redis有序集合中取出20個(gè)元素,并且附帶對(duì)應(yīng)的score。
因?yàn)橛?code>mGet柠衅、hMGet
等方便的指令,我下意識(shí)地在鍵盤上輸入zMScore
籍琳,可奈何phpredis擴(kuò)展
中不帶有這兒方法,查閱資料之后贷祈,發(fā)現(xiàn)Redis本生就不帶有這個(gè)方法趋急。
問題
背景所述的Redis操作時(shí)放在接口中的,采用for循環(huán)用zScore
操作必然會(huì)加大程序和Redis的數(shù)據(jù)交互次數(shù)势誊,導(dǎo)致接口速度變慢呜达。
思考
1、類似于MySQL粟耻,Redis也是支持事務(wù)的查近,利用multi
和exec
操作將20個(gè)zScore
包起來(lái);
2挤忙、編寫Lua腳本霜威,利用eval
方法進(jìn)行操作;
實(shí)踐
代碼
- for循環(huán)方式
<?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);
- 事務(wù)方式
<?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);
結(jié)果
- for循環(huán)方式:關(guān)鍵部分的耗時(shí)平均在0.6ms册烈;
- 事務(wù)方式:關(guān)鍵部分的耗時(shí)平均在0.6ms戈泼;
- eval方式:關(guān)鍵部分的耗時(shí)平均在0.2ms;