前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis常用技术-----流水线(Pipelined)

Redis常用技术-----流水线(Pipelined)

作者头像
秃头哥编程
发布2019-06-11 17:37:25
1.2K1
发布2019-06-11 17:37:25
举报
文章被收录于专栏:秃头哥编程秃头哥编程

在事务中Redis提供了队列,可以批量执行任务,这样性能就比较高,但使用multi...exec事务命令是有系统开销的,因为它会检测对应的锁和序列化命令。有时我们希望在没有任何附加条件的情况下使用队列批量执行一系列命令,这时可以使用Redis的流水线(pipelined)技术。

实际中Redis的读写速度十分快,而系统的瓶颈往往是在网络通信中的延时。比如当命令1在T1时刻发送到Redis服务器后,服务器很快执行完命令1,而命令2在T2时刻却没有通过网络送达Redis服务器,这样就变成了Redis服务器在等待命令2的到来,当命令2到达且被执行后,命令3还没到,又得继续等待,以此类推,这样Redis的等待时间就会很长,很多时候在空闲的状态,而问题出现在网络的延迟中,造成了系统的瓶颈。

为了解决这个问题,可以使用Redis的流水线,但Redis的流水线是一种通信协议,没有办法通过客户端演示,不过可以通过Java API或使用Spring操作它。

/**
 * 测试Redis流水线 
 * @author liu
 */
public class TestPipelined {
    
    /**
     * 使用Java API测试流水线的性能
     */
    @SuppressWarnings({ "unused", "resource" })
    @Test
    public void testPipelinedByJavaAPI() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(20);
        jedisPoolConfig.setMaxTotal(10);
        jedisPoolConfig.setMaxWaitMillis(20000);
        
        JedisPool jedisPool = new JedisPool(jedisPoolConfig,"localhost",6379);
        Jedis jedis = jedisPool.getResource();
        long start = System.currentTimeMillis();
        // 开启流水线
        Pipeline pipeline = jedis.pipelined();
        // 测试10w条数据读写
        for(int i = 0; i < 100000; i++) {
            int j = i + 1;
            pipeline.set("key" + j, "value" + j);
            pipeline.get("key" + j);
        }
        // 只执行同步但不返回结果
        //pipeline.sync();
        // 以list的形式返回执行过的命令的结果
        List<Object> result = pipeline.syncAndReturnAll();
        long end = System.currentTimeMillis();
        // 计算耗时
        System.out.println("耗时" + (end - start) + "毫秒");
    }
    
    /**
     * 使用RedisTemplate测试流水线
     */
    @SuppressWarnings({ "resource", "rawtypes", "unchecked", "unused" })
    @Test
    public void testPipelineBySpring() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        RedisTemplate rt = (RedisTemplate)applicationContext.getBean("redisTemplate");
        SessionCallback callback = (SessionCallback)(RedisOperations ops)->{
            for(int i = 0; i < 100000; i++) {
                int j = i + 1;
                ops.boundValueOps("key" + j).set("value" + j);
                ops.boundValueOps("key" + j).get();
            }
            return null;
        };
        long start = System.currentTimeMillis();
        // 执行Redis的流水线命令
        List result = rt.executePipelined(callback);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

书上写的测试结果为:使用Java API耗时在550ms到700ms之间,也就是不到1s就完成了10万次读写,使用Spring 耗时在1100ms到1300ms之间。

我的测试结果:使用Java API耗时在13s左右,使用Spring直接内存溢出,这说明我得换电脑了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 秃头哥编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档