redis管道(pipeline)

redis pipeline

redis是一个cs模式的tcp server,使用和http类似的请求响应协议。一个client可以通过一个socket连接发起多个请求命令。每个请求命令发出后client通常 会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client。基本的通信过程如下:

(Client)127.0.0.1:6379> incr x

(Server)(integer) 1

(Client)127.0.0.1:6379> incr x

(Server) (integer) 2

(Client)127.0.0.1:6379> incr x

(Server) (integer) 3

(Client)127.0.0.1:6379> incr x

(Server) (integer) 4

基 本上四个命令需要8个tcp报文才能完成。由于通信会有网络延迟,假如从client和server之间的包传输时间需要0.125秒。那么上面的四个命 令8个报文至少会需要1秒才能完成。这样即使redis每秒能处理100个命令,而我们的client也只能一秒钟发出四个命令。这显示没有充分利用 redis的处理能力。除了可以利用mget,mset 之类的单条命令处理多个key的命令外
我们还可以利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端。通信过程如下:

(Client)127.0.0.1:6379> incr x

(Client)127.0.0.1:6379> incr x

(Client)127.0.0.1:6379> incr x

(Client)127.0.0.1:6379> incr x

(Server)(integer) 1

(Server) (integer) 2

(Server) (integer) 3

(Server) (integer) 4

假 设不会因为tcp 报文过长而被拆分。可能两个tcp报文就能完成四条命令,client可以将四个incr命令放到一个tcp报文一起发送,server则可以将四条命令 的处理结果放到一个tcp报文返回。通过pipeline方式当有大批量的操作时候。我们可以节省很多原来浪费在网络延迟的时间。需要注意到是用 pipeline方式打包命令发送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并是不是打 包的命令越多越好。具体多少合适需要根据具体情况测试。下面是个jredis客户端使用pipeline的测试:

public class
RedisTest {

Jedis
j=null;

public RedisTest() {

j = new
Jedis("192.168.168.128",6379);

// TODO Auto-generated constructor stub

}

public static void main(String[] args) {

// TODO Auto-generated method stub

int count = 10000;

long start = System.currentTimeMillis();

new
RedisTest().withOutPipeline(count);

long end = System.currentTimeMillis();

System.out.println("withOutPipeline:"+(end-start));

start = System.currentTimeMillis();

new
RedisTest().usePipeline(count);

end = System.currentTimeMillis();

System.out.println("usePipeline:"+(end-start));

}

public void usePipeline(int count){

Pipeline
p = j.pipelined();

try {

for(int i=0;i<count;i++){

p.incr("usePipe");

}

p.sync();

}
catch
(Exception e) {

// TODO: handle exception

}finally{

if(j!=null){

j.disconnect();

}

}

}

public void withOutPipeline(int count){

try {

for(int i=0;i<count;i++){

j.incr("usePipe");

}

}
catch
(Exception e) {

// TODO: handle exception

}finally{

if(j!=null){

j.disconnect();

}

}

}

}

输出:

withOutPipeline:2302

usePipeline:130

测试结果还是很明显有较大的差距,所以多次操作用pipeline还是有明显的优势。我用的是Win7中的Jedis Java客户端程序连接局域网的Linux虚拟机上的Redis Server。

时间: 2024-11-03 05:30:46

redis管道(pipeline)的相关文章

redis使用管道pipeline提升批量操作性能(php演示)

Redis是一个TCP服务器,支持请求/响应协议. 在Redis中,请求通过以下步骤完成: 客户端向服务器发送查询,并从套接字读取,通常以阻塞的方式,用于服务器响应. 服务器处理命令并将响应发送回客户端. 如果需要一次执行多个redis命令,以往的方式需要发送多次命令请求,有redis服务器依次执行,并返回结果, 为了解决此类问题,设计者设计出了redis管道命令: 客户端可以向服务器发送多个请求,而不必等待回复,并最终在一个步骤中读取回复,从而大大增加了协议性能 做了测试,使用pipeline

redis之pipeline使用

redis之pipeline 我们要完成一个业务,可能会对redis做连续的多个操作,这有很多个步骤是需要依次连续执行的.这样的场景,网络传输的耗时将是限制redis处理量的主要瓶颈. 那么此时就可以引入pipeline了,pipeline管道就是解决执行大量命令时.会产生大量同学次数而导致延迟的技术. 其实原理很简单,pipeline就是把所有的命令一次发过去,避免频繁的发送.接收带来的网络开销,redis在打包接收到一堆命令后,依次执行,然后把结果再打包返回给客户端. 1 public St

使用Redis管道提升性能

Redis 的 管道 (pipelining)是用来打包多条无关命令批量执行,以减少多个命令分别执行带来的网络交互时间.在一些批量操作数据的场景,使用管道可以显著提升 Redis 的读写性能. 原理演示 Redis 的管道实质就是命令打包批量执行,多次网络交互减少到单次.使用管道和不使用管道时的交互过程如下: 我们使用 nc 命令来直观感受下 Redis 管道的使用过程: # 安装nc命令 $ yum install nc # nc打包多个命令 $ (printf "PING\r\nPING\r

Redis 管道技术

Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务.这意味着通常情况下一个请求会遵循以下步骤: 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应. 服务端处理命令,并将结果返回给客户端. Redis 管道技术 Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应. 实例 查看 redis 管道,只需要启动 redis 实例并输入以下命令: $(echo -en "PING\r\n SE

[Linux] 流 ( Stream )、管道 ( Pipeline ) 、Filter- 笔记

流 ( Stream ) 1. 流,是指可使用的数据元素一个序列. 2. 流,可以想象为是传送带上等待加工处理的物品,也可以想象为工厂流水线上的物品. 3. 流,可以是无限的数据. 4. 有一种功能,处理这一个流同时产生着另一个流.这种功能被成为 过滤 ( Filter ).使用管道 ( pipelie ) 将这些功能进行连接. Unix 管道 ( Pipeline ) 1. 管道连接着处理元素,一个处理元素的输出是下一个处理处理元素的输入. 2. 管道能加快数据处理速度. 2. Unix 下的

Redis利用Pipeline加速查询速度的方法

1. RTT Redis 是一种基于客户端-服务端模型以及请求/响应协议的TCP服务.这意味着通常情况下 Redis 客户端执行一条命令分为如下四个过程: 发送命令 命令排队 命令执行 返回结果 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应.服务端处理命令,并将结果返回给客户端.客户端和服务端通过网络进行连接.这个连接可以很快,也可能很慢.无论网络如何延迟,数据包总是能从客户端到达服务端,服务端返回数据给客户端. 这个时间被称为 RTT (Round

php读取文件使用redis的pipeline(管道)导入大批量数据

需求:需要做一个后台上传TXT文件,读取其中的内容,然后导入redis库中.要求速度快,并且支持至少10W以上的数据,而内容也就一个字段存类似openid和QQ 传统做法:我一开始做的时候就老套路,遍历.hset,然后就发现非常的慢,一千条数据就花了30-32秒,当时就觉得不行,于是就请教了一个大佬,然后就得知了方法 我生成了20W的数据用来做测试,文件大小6M多. 话不多说,直接贴代码了 $lines  = file_get_contents($_FILES['file']['tmp_name

redis之管道——pipeline

redis 是 CS 模式,Redis客户端与Redis之间使用TCP协议进行连接,一个客户端可以通过一个socket连接发起多个请求命令,每个请求命令发出后client通常会阻塞并等待redis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client,因此当执行多条命令的时候都需要等待上一条命令执行完毕才能执行.如果一次性批量数据单次操作,会有网络延迟.而redis也是单线程的. 而Pipelining可以满足批量的操作,把多个命令连续的发送给Redis Server,然后

redis 管道(Pipelining)

有时,我们需要采用异步方式,一次发送多个指令,不同步等待其返回结果. 利用pipeline的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回, 而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端(ps:有点类似存储过程的特点). 这样可以取得非常好的执行效率.这就是管道,调用方法如下: @Test public void test4Pipelined() {     Jedis jedis = new Jedis("localhost"