使用redis pipeline打包执行多条任务

Posted hgditren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用redis pipeline打包执行多条任务相关的知识,希望对你有一定的参考价值。

这里重点说一下pipeline。

管道(pipeline)可以一次性发送多条命令并在执行完后一次性将结果返回。

执行流程:
打包开始->缓存->打包结束->发送->执行->返回执行结果。

优点:
1.pipeline 通过减少客户端与 redis 的通信次数来实现降低往返延时时间。
pipeline 通过打包命令,一次性执行,可以节省 连接->发送命令->返回结果 所产生的往返时间,减少网络I/O的调用次数。

2.而且 Pipeline 实现的原理是队列,而队列的原理是时先进先出,这样就保证数据的顺序性。

通俗点:pipeline就是把一组命令进行打包,然后一次性通过网络发送到Redis。同时将执行的结果批量的返回回来。

缺点:
1.pipeline 每批打包的命令不能过多,因为 pipeline 方式打包命令再发送,那么 redis 必须在处理完所有命令前先缓存起所有命令的处理结果。这样就有一个内存的消耗。

2.pipeline 是责任链模式,这个模式的缺点是,每次它对于一个输入都必须从链头开始遍历(参考Http Server处理请求就能明白),这确实存在一定的性能损耗。

最重要的注意点:
pipeline 不保证原子性,如果要求原子性的,不推荐使用 pipeline。

下面是php redis扩展官方用法介绍

multi, exec, discard.

Description: Enter and exit transactional mode.
Parameters

(optional) Redis::MULTI or Redis::PIPELINE. Defaults to Redis::MULTI. A Redis::MULTI block of commands runs as a single transaction; a Redis::PIPELINE block is simply transmitted faster to the server, but without any guarantee of atomicity. discard cancels a transaction.
Return value

multi() returns the Redis instance and enters multi-mode. Once in multi-mode, all subsequent method calls return the same object until exec() is called.
Example

$ret = $redis->multi()
    ->set(key1, val1)
    ->get(key1)
    ->set(key2, val2)
    ->get(key2)
    ->exec();

/*
$ret == Array(0 => TRUE, 1 => val1, 2 => TRUE, 3 => val2);
*/

这里特意提到一句:

意思是pipeline的目的是快速的将打包的操作传输到redis服务,但不能保证原子性。

php代码实现:

//开启pipeline模式
$pipelineObj = $redis->multi(Redis::PIPELINE);

//在$pipelineObj对象上增加打包任务操作
$pipelineObj->set(key1, val1)
    ->get(key1)
    ->set(key2, val2)
    ->get(key2);

//或者这样写
$pipelineObj->set(key1, val1);
$pipelineObj->get(key1);
$pipelineObj->set(key2, val2);
$pipelineObj->get(key2);

//打包完成,执行exec发送执行任务。
$pipelineObj->exec();

参考
官网pipeline介绍

php redis官方扩展

以上是关于使用redis pipeline打包执行多条任务的主要内容,如果未能解决你的问题,请参考以下文章

使用Redis管道提升性能

使用Redis管道提升性能

Pipeline

redis之管道——pipeline

Redis 管道事务Lua 脚本对比

Redis-主从用服务冗余避免单点