一、请求和响应
发送请求的流程:
1、客户端向服务端发送一个请求,并监听Scoket返回,通常是以阻塞模式,等待服务端响应。
2、服务端处理命令,并将结果返回给客户端。
无论网络如何延时或者其他的阻塞发生,数据包总是能从客户端到达服务器,并从服务器返回数据回复客户端。这个时间称为RTT(往返时间);
如果客户端需要在一个批处理中执行多次请求时很容易影响性能;每秒的请求数也会少之又少;
所以就有了下面的方法,用来改善这种情况;
二、Redis 管道 ------ Pipelining
pipeline通过减少客户端与redis的通信次数来实现降低往返延时时间,而且pipiline实现原理是队列,而队列的原理是先进先出,这样就保证数据的顺序性;默认的个数是53条
定义:一次请求/响应服务器能实现处理新的请求即使旧的请求还未被响应。这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该回复。
特点:
批量流水线发送;
一次返回相应的响应;
应用场景:
1、由于是批量流水线发送,所以每个请求之间需要无状态,即后请求不依赖前请求的响应结果;
2、由于一次返回响应,所以响应中可能会存在有些请求命令执行成功,有些失败。所以应用场景必须能够容忍数据处理错误或者数据丢失的风险,或者能够接受通过其他机制弥补丢失或者错误的数据方式;
重点说明:使用管道发送命令时,服务器将被迫回复一个队列答复,占用很多内存。如果需要发送大量的命令,最好是把它们按照合理数量分批次的处理。例如10K的命令,读回复,然后再发送另一个10K的命令。这样的速度几乎是相同的,但是在回复这10K命令队列需要非常大量的内存用来组织返回数据内容。
php + Pipelining 简易代码示例:
<?php
$redis = new Redis();
$redis->connect('localhost',6379);
$redis->auth('1234567890'); //auth 为redis服务请求设置一个密码
$pipe = $redis->multi(Redis::PIPELINE); //multi标记一个事务块的开始
for($i=0;$i<10000,$i++){
$pipe->set("key::$i",str_pad($i,4,'0',0));
$pipe->get("key::$i");
}
$replies = $pipe->exec();//exec 执行所有multi之后的命令,执行事务中所有在排队等待的指令并将链接恢复到正常。
print_r($replies);