Redis(十七):一括操作Pipeline

5115 ワード

ほとんどの場合、リクエスト-対応するメカニズムによってredisを操作します.このモードのみを使用する一般的なステップは、jedisインスタンスを取得し、jedisのget/putメソッドを介してredisとインタラクティブになることである.redisは単一スレッドであるため、次のリクエストは、実行を続行する前のリクエストの実行が完了するまで待たなければなりません.しかし、Pipelineモードを使用すると、クライアントは、サービス側の返信を待つことなく、複数のコマンドを一度に送信することができる.これにより、ネットワーク往復時間が大幅に短縮され、システム性能が向上します.
この2つのモードの効率の違いを1つの例でテストします.
   
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              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              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件をグループで送信して、第1のモードで実現すれば、この要求は、クライアントに応答するのに長い時間がかかります.この遅延は長すぎます.クライアントリクエストにタイムアウト時間が5秒設定されていると、異常が投げ出されるに違いありません.また、自分のグループでメールを送るのにリアルタイム性がそれほど高くないので、pipelineを使うのが一番です.