华为网站建设的目标是否明确,凡科门店通包括哪些产品,企业门户网站建设报告,网上商城开发方案我们希望在没有任何附加条件的场景下去使用队列批量执行一系列的命令#xff0c;从而提高系统性能#xff0c;这就是 Redis 的流水线#xff08;pipelined#xff09;技术。而现实中 Redis 执行读/写速度十分快#xff0c;而系统的瓶颈往往是在网络通信中的延时#xff0…我们希望在没有任何附加条件的场景下去使用队列批量执行一系列的命令从而提高系统性能这就是 Redis 的流水线pipelined技术。而现实中 Redis 执行读/写速度十分快而系统的瓶颈往往是在网络通信中的延时如图所示。
在实际的操作中往往会发生这样的场景当命令 1 在时刻 T1 发送到 Redis 服务器后服务器就很快执行完了命令 1而命令 2 在 T2 时刻却没有通过网络送达 Redis 服务器这样就变成了 Redis 服务器在等待命令 2 的到来当命令 2 送达被执行后而命令 3 又没有送达 RedisRedis 又要继续等待依此类推这样 Redis 的等待时间就会很长很多时候在空闲的状态而问题出在网络的延迟中造成了系统瓶颈。
为了解决这个问题可以使用 Redis 的流水线但是 Redis 的流水线是一种通信协议没有办法通过客户端演示给大家不过我们可以通过 Java API 或者使用 Spring 操作它先使用 Java API 去测试一下它的性能代码如下所示。
Jedis jedis pool.getResource();
long start System.currentTimeMillis();
// 开启流水线
Pipeline pipeline jedis.pipelined();
// 这里测试10万条的读/写2个操作
for (int i 0; i 100000; i) {int j i 1;pipeline.set(pipeline_key_ j, pipeline_value_ j);pipeline.get(pipeline_key_ j);
}
// pipeline.sync(); //这里只执行同步但是不返回结果
// pipeline.syncAndReturnAll ();将返回执行过的命令返回的List列表结果
List result pipeline.syncAndRetrunAll();
long end System.currentTimeMillis();
// 计算耗时
System.err.println(耗时 (end - start) 毫秒);在电脑上测试这段代码它的耗时在 550 毫秒到 700 毫秒之间也就是不到 1 秒的时间就完成多达 10 万次读/写可见其性能远超数据库。我的测试是 1 秒 2 万多次可见使用流水线后其性能提高了数倍之多效果十分明显。执行过的命令的返回值都会放入到一个 List 中。
注意这里只是为了测试性能而已当你要执行很多的命令并返回结果的时候需要考虑 List 对象的大小因为它会“吃掉”服务器上许多的内存空间严重时会导致内存不足引发 JVM 溢出异常可以考虑使用迭代的方式去处理。
在 Spring 中执行流水线和执行事务的方法如出一辙都比较简单使用 RedisTemplate 提供的 executePipelined 方法即可。下面将上面代码的功能修改为 Spring 的形式供大家参考代码如下所示。
public static void testPipeline() {Applicationcontext applicationcontext new ClassPathXmlApplicationContext(applicationcontext.xml);RedisTemplate redisTemplate applicationcontext.getBean(RedisTemplate.class);// 使用Java8的Lambda表达式SessionCallback callBack (SessionCallback) (RedisOperations ops)- {for (int i 0; i100000; i) {int j i 1;ops . boundValueOps (pipeline_key_ j ).set(piepeline_value_j);ops.boundValueOps(pipeline_key_ j).get();}return null;};long start System.currentTimeMillis();//执行Redis的流水线命令List resultList redisTemplate.executePipelined(callBack);long end System.currentTimeMillis();System.err.println(end-start);
}我对这段代码进行了测试其性能慢于不用 RedisTemplate 的测试消耗的时间大约在 1 100 毫秒到 1 300 毫秒之间也就是消耗的时间大约是其两倍但也属于完全可以接受的性能范围同样的在执行很多命令的时候也需要考虑其对运行环境内存空间的开销。