【Laravel】我记下了Redis::pipeline非常快速的笔记
最近,我在业务中负责对其他工程师的代码进行了评论,在此将其作为备忘录保存下来。
在我所属的项目中,我们使用PHP × Laravel,并且这次有以下的实施要求。
将多个列表类型的键设置到Redis中。
然后进行了如下实施。
foreach($key_map as $key => $value) {
Redis::lpush($key, $value);
Redis::expire($key, self::CACHE_EXPIRE_TIME);
}
如果你认为可以正常运行,而且不需要担心性能的话,就可以不去理会,但既然有机会,那么可以去看一下Laravel官方文档( https://readouble.com/laravel/5.4/ja/redis.html ),上面有这样的命令。
如果需要在一次操作中向服务器发送多个命令,应该使用管道。pipeline方法接受一个参数,并返回一个“闭包”,该闭包接受Redis实例。您可以使用此Redis实例发出所有命令,并且可以在一次操作中将它们全部执行完成。
Redis::pipeline(function ($pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", $i);
}
});
嗯嗯,实例内发出所有命令并在一次操作中全部执行,确实看起来性能不错。
就这样,随便创造一个artisan命令并试一试。
这样做看起来像这样。
// 直接
$startTime = microtime(true);
for ($i = 0; $i < $count; $i++) {
Redis::lpush('test_key' . $i, 'hoge');
}
$runningTime = microtime(true) - $startTime;
var_dump('straight running time: ' . $runningTime . ' [s]');
// pipeline
$startTime = microtime(true);
$redis = Redis::connection('redis_0');
$redis->pipeline(function ($pipe) use($count) {
for ($i = 0; $i < $count; $i++) {
$pipe->lpush('test_key_pipeline' . $i, 'hoge');
}
});
$runningTime = microtime(true) - $startTime;
var_dump('pipeline running time: ' . $runningTime . ' [s]');
↓↓结果↓↓
// 10件一括
# php artisan redis_test 10
string(42) "straight running time: 0.0122230052948 [s]"
string(46) "pipeline running time: 0.00022292137145996 [s]"
// 1000件一括
# php artisan redis_test 1000
string(43) "straight running time: 0.15764403343201 [s]"
string(45) "pipeline running time: 0.0015499591827393 [s]"
从性能来看,大约提高了100倍。似乎没有使用的理由。因为set等原本就可以原子性地执行,所以不需要使用,但是在需要批量执行的情况下,可以考虑使用列表或哈希类型。
当有多个Redis服务器时,需要注意的是因为同样的命令会发送到所有服务器,可能会出现浪费的情况,所以可以根据连接将其分组,并为每个Redis服务器传递适当的键列表。
我将继续努力学习。