zoukankan      html  css  js  c++  java
  • Redis(十七):批量操作Pipeline

    大多数情况下,我们都会通过请求-相应机制去操作redis。只用这种模式的一般的步骤是,先获得jedis实例,然后通过jedis的get/put方法与redis交互。由于redis是单线程的,下一次请求必须等待上一次请求执行完成后才能继续执行。然而使用Pipeline模式,客户端可以一次性的发送多个命令,无需等待服务端返回。这样就大大的减少了网络往返时间,提高了系统性能。

      下面用一个例子测试这两种模式在效率上的差别:

       

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    public class PiplineTest {
        private static int count = 10000;
     
        public static void main(String[] args){
            useNormal();
            usePipeline();
        }
     
        public static void usePipeline(){
            ShardedJedis jedis = getShardedJedis();
            ShardedJedisPipeline pipeline = jedis.pipelined();
            long begin = System.currentTimeMillis();
            for(int i = 0;i<count;i++){
                pipeline.set("key_"+i,"value_"+i);
            }
            pipeline.sync();
            jedis.close();
            System.out.println("usePipeline total time:" + (System.currentTimeMillis() - begin));
        }
     
        public static void useNormal(){
            ShardedJedis jedis = getShardedJedis();
            long begin = System.currentTimeMillis();
            for(int i = 0;i<count;i++){
                jedis.set("key_"+i,"value_"+i);
            }
            jedis.close();
            System.out.println("useNormal total time:" + (System.currentTimeMillis() - begin));
        }
     
        public static ShardedJedis getShardedJedis(){
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            poolConfig.setMaxTotal(2);
            poolConfig.setMaxIdle(1);
            poolConfig.setMaxWaitMillis(2000);
            poolConfig.setTestOnBorrow(false);
            poolConfig.setTestOnReturn(false);
            JedisShardInfo info1 = new JedisShardInfo("127.0.0.1",6379);
            JedisShardInfo info2 = new JedisShardInfo("127.0.0.1",6379);
            ShardedJedisPool pool = new ShardedJedisPool(poolConfig, Arrays.asList(info1,info2));
            return pool.getResource();
        }
    }

     输出结果:

    1
    2
    useNormal total time:772
    usePipeline total time:112

     从测试的结果可以看出,使用pipeline的效率要远高于普通的访问方式。

     那么问题来了,在什么样的情景下适合使用pipeline呢?

     有些系统可能对可靠性要求很高,每次操作都需要立马知道这次操作是否成功,是否数据已经写进redis了,那这种场景就不适合。

    还有的系统,可能是批量的将数据写入redis,允许一定比例的写入失败,那么这种场景就可以使用了,比如10000条一下进入redis,可能失败了2条无所谓,后期有补偿机制就行了,比如短信群发这种场景,如果一下群发10000条,按照第一种模式去实现,那这个请求过来,要很久才能给客户端响应,这个延迟就太长了,如果客户端请求设置了超时时间5秒,那肯定就抛出异常了,而且本身群发短信要求实时性也没那么高,这时候用pipeline最好了。

  • 相关阅读:
    NHibernate之映射文件配置说明
    JS jQuery json日期格式问题的办法
    Spring.net 配置说明
    NHibernate常见问题及解决方法
    Could not load type 'System.Web.Mvc.ViewPage<dynamic>' in asp.net mvc2 after publishing the website
    启用SQLite的Data Provider 运行WECOMPANYSITE时遇到ERROR CREATING CONTEXT 'SPRING.ROOT': ERROR THROWN BY A DEPENDENCY OF OBJECT 'SYSTEM.DATA.SQLITE'
    Nuget 命令 NuGet 管理项目库
    vs2013(vs2015) 打开vs2010 找不到此项目类型所基于的应用程序 MVC2 升级 MVC5 不能加载Web项目
    JsonResult作为Action返回值时的错误
    MVC 数据验证
  • 原文地址:https://www.cnblogs.com/shamo89/p/9872841.html
Copyright © 2011-2022 走看看