博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis之Pipeline使用注意事项
阅读量:5171 次
发布时间:2019-06-13

本文共 3035 字,大约阅读时间需要 10 分钟。

一般情况下,使用redis去put/get都是先拿到一个jedis实例,然后操作,然后释放连接;这种模式是  请求-响应,请求-响应.这种模式,下一次请求必须得等第一次请求响应回来之后才可以,因为redis是单线程的,按部就班,一步一步来。而pipeline管道改变了这种请求模式,客户端可以一次发送多个命令,无须等待服务器的返回,请求,请求,请求,响应,响应,响应.这种模式这就大大减少了影响性能的关键因素-网络往返时间.重要说明: 使用管道发送命令时,服务器将被迫回复一个队列答复,占用很多内存。所以,如果你需要发送大量的命令,最好是把他们按照合理数量分批次的处理,例如10K的命令,读回复,然后再发送另一个10k的命令,等等。这样速度几乎是相同的,但是在回复这10k命令队列需要非常大量的内存用来组织返回数据内容。Jedis jedis = poolFactory.getjedisResourcePool().getResource();Pipeline pl = jedis.pipelined();Pipeline 的特点:1、Pipeline 实现的原理是队列,而队列的原理是时先进先出,这样就保证数据的顺序性下面就上面两种模式以及JDK的map三者做一个性能比较[java] view plain copypackage redis;    import java.util.concurrent.BlockingQueue;  import java.util.concurrent.LinkedBlockingQueue;    import redis.clients.jedis.ShardedJedis;  import redis.clients.jedis.ShardedJedisPipeline;    /**  * @Type ShardRedisDemo.java  * @Desc  * @author chiwei  * @date 2016年6月13日 下午3:24:25  * @version  */  public class ShardRedisDemo {        public static void main(String[] args) throws InterruptedException {          ShardRedisClient src = new ShardRedisClient();          src.setServers("redis://172.23.26.135:7379");          src.init();          int count = 10000;          ShardedJedis sj = src.getResource();          long begin = System.currentTimeMillis();          for (int i = 0; i < count; i++) {              sj.set("a" + i, "v" + i);          }          sj.close();          System.out.println(System.currentTimeMillis() - begin);          sj = src.getResource();          ShardedJedisPipeline p = sj.pipelined();          begin = System.currentTimeMillis();          for (int i = 0; i < count; i++) {              p.set("ap" + i, "vp" + i);          }          p.sync();          sj.close();          System.out.println(System.currentTimeMillis() - begin);          BlockingQueue
logQueue = new LinkedBlockingQueue
(); begin = System.currentTimeMillis(); for (int i = 0; i < count; i++) { logQueue.put("i=" + i); } System.out.println(System.currentTimeMillis() - begin); } } /** * Revision history * ------------------------------------------------------------------------- * * Date Author Note * ------------------------------------------------------------------------- * 2016年6月13日 chiwei create */ 结果如下:[plain] view plain copy45027 116 11 大家看相对时间就行了,我测试时是经过VPN连的redis,由此结果可见pipeline的性能惊人的高。2、关于Pipeline 同步数据的问题A)、Pipeline 有与redis形同的操作,但是在数据落盘的时候需要在执行的方法后添加sync()方法,如果insert时有多条数据,在数据拼接完之后,在执行sync()方法,这样可以提高效率。B)、如果在hget()时没有sync()时会报,没有在hget()同步数据C)、如果在hset(),hdel(),hget()获取数据时都没有执行sync()方法,但是在最后执行了pl.close()方法,Pipeline 同样会执行sync()方法,详细的代码如下:Pipeline类下的close()方法中的clear(),有sync()方法,但是pipeline适合于什么样的场景使用呢?有些系统可能对可靠性要求很高,每次操作都需要立马知道这次操作是否成功,是否数据已经写进redis了,那这种场景就不适合。还有的系统,可能是批量的将数据写入redis,允许一定比例的写入失败,那么这种场景就可以使用了,比如10000条一下进入redis,可能失败了2条无所谓,后期有补偿机制就行了,比如短信群发这种场景,如果一下群发10000条,按照第一种模式去实现,那这个请求过来,要很久才能给客户端响应,这个延迟就太长了,如果客户端请求设置了超时时间5秒,那肯定就抛出异常了,而且本身群发短信要求实时性也没那么高,这时候用pipeline最好了。

 

转载于:https://www.cnblogs.com/xiaolei2017/p/8674933.html

你可能感兴趣的文章
【前台技术】-播放音频
查看>>
ElasticSearch High Level REST API【3】Scroll 滚屏
查看>>
关于STM32定时器使用的一个注意事项(以此为前车之鉴,重要!)
查看>>
Mybatis实现高级映射一对一、一对多查询
查看>>
JavaScript面向对象
查看>>
Codeforces Round #453 (Div. 1)
查看>>
[51单片机] 四相五线减速比为1/64步进电机驱动设计
查看>>
leetcode136只出现一次的数字
查看>>
docker tar 镜像 容器相互转换
查看>>
合成(Composite)模式
查看>>
.net EventHandler 事件处理
查看>>
[导入]2008李幼斌电视剧力作《我是太阳》全42集
查看>>
vs2013编译obs源码
查看>>
PHP 实现简单购物车功能(2)
查看>>
(9.19更新:八戒退款) 砸进七万块,没想到你是这样的猪八戒网
查看>>
bnu 29064, 期望 水题
查看>>
C语言使用SQLite3数据库
查看>>
Linux安装virgo
查看>>
cygwin安装
查看>>
Hero In Maze
查看>>