<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

    Redis的Java客戶端Jedis的八種調用方式(事務、管道、分布式)介紹

    在這里對jedis關于事務、管道和分布式的調用方式做一個簡單的介紹和對比:

    一、普通同步方式

    最簡單和基礎的調用方式,

    @Test public void test1Normal() {     Jedis jedis = new Jedis("localhost");     long start = System.currentTimeMillis();     for (int i = 0; i < 100000; i++) {         String result = jedis.set("n" + i, "n" + i);     }     long end = System.currentTimeMillis();     System.out.println("Simple SET: " + ((end - start)/1000.0) + " seconds");     jedis.disconnect(); }

    很簡單吧,每次set之后都可以返回結果,標記是否成功。

    二、事務方式(Transactions)

    redis的事務很簡單,他主要目的是保障,一個client發起的事務中的命令可以連續的執行,而中間不會插入其他client的命令。

    看下面例子:

    @Test public void test2Trans() {     Jedis jedis = new Jedis("localhost");     long start = System.currentTimeMillis();     Transaction tx = jedis.multi();     for (int i = 0; i < 100000; i++) {         tx.set("t" + i, "t" + i);     }     List<Object> results = tx.exec();     long end = System.currentTimeMillis();     System.out.println("Transaction SET: " + ((end - start)/1000.0) + " seconds");     jedis.disconnect(); }

    我們調用jedis.watch(…)方法來監控key,如果調用后key值發生變化,則整個事務會執行失敗。另外,事務中某個操作失敗,并不會回滾其他操作。這一點需要注意。還有,我們可以使用discard()方法來取消事務。

    三、管道(Pipelining)

    有時,我們需要采用異步方式,一次發送多個指令,不同步等待其返回結果。這樣可以取得非常好的執行效率。這就是管道,調用方法如下:

    @Test public void test3Pipelined() {     Jedis jedis = new Jedis("localhost");     Pipeline pipeline = jedis.pipelined();     long start = System.currentTimeMillis();     for (int i = 0; i < 100000; i++) {         pipeline.set("p" + i, "p" + i);     }     List<Object> results = pipeline.syncAndReturnAll();     long end = System.currentTimeMillis();     System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds");     jedis.disconnect(); }

    四、管道中調用事務

    就Jedis提供的方法而言,是可以做到在管道中使用事務,其代碼如下:

    @Test public void test4combPipelineTrans() {     jedis = new Jedis("localhost");      long start = System.currentTimeMillis();     Pipeline pipeline = jedis.pipelined();     pipeline.multi();     for (int i = 0; i < 100000; i++) {         pipeline.set("" + i, "" + i);     }     pipeline.exec();     List<Object> results = pipeline.syncAndReturnAll();     long end = System.currentTimeMillis();     System.out.println("Pipelined transaction: " + ((end - start)/1000.0) + " seconds");     jedis.disconnect(); }

    但是經測試(見本文后續部分),發現其效率和單獨使用事務差不多,甚至還略微差點。

    五、分布式直連同步調用

    @Test public void test5shardNormal() {     List<JedisShardInfo> shards = Arrays.asList(             new JedisShardInfo("localhost",6379),             new JedisShardInfo("localhost",6380));      ShardedJedis sharding = new ShardedJedis(shards);      long start = System.currentTimeMillis();     for (int i = 0; i < 100000; i++) {         String result = sharding.set("sn" + i, "n" + i);     }     long end = System.currentTimeMillis();     System.out.println("Simple@Sharing SET: " + ((end - start)/1000.0) + " seconds");      sharding.disconnect(); }

    這個是分布式直接連接,并且是同步調用,每步執行都返回執行結果。類似地,還有異步管道調用。

    六、分布式直連異步調用

    @Test public void test6shardpipelined() {     List<JedisShardInfo> shards = Arrays.asList(             new JedisShardInfo("localhost",6379),             new JedisShardInfo("localhost",6380));      ShardedJedis sharding = new ShardedJedis(shards);      ShardedJedisPipeline pipeline = sharding.pipelined();     long start = System.currentTimeMillis();     for (int i = 0; i < 100000; i++) {         pipeline.set("sp" + i, "p" + i);     }     List<Object> results = pipeline.syncAndReturnAll();     long end = System.currentTimeMillis();     System.out.println("Pipelined@Sharing SET: " + ((end - start)/1000.0) + " seconds");      sharding.disconnect(); }

    七、分布式連接池同步調用

    如果,你的分布式調用代碼是運行在線程中,那么上面兩個直連調用方式就不合適了,因為直連方式是非線程安全的,這個時候,你就必須選擇連接池調用。

    @Test public void test7shardSimplePool() {     List<JedisShardInfo> shards = Arrays.asList(             new JedisShardInfo("localhost",6379),             new JedisShardInfo("localhost",6380));      ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);      ShardedJedis one = pool.getResource();      long start = System.currentTimeMillis();     for (int i = 0; i < 100000; i++) {         String result = one.set("spn" + i, "n" + i);     }     long end = System.currentTimeMillis();     pool.returnResource(one);     System.out.println("Simple@Pool SET: " + ((end - start)/1000.0) + " seconds");      pool.destroy(); }

    上面是同步方式,當然還有異步方式。

    八、分布式連接池異步調用

    @Test public void test8shardPipelinedPool() {     List<JedisShardInfo> shards = Arrays.asList(             new JedisShardInfo("localhost",6379),             new JedisShardInfo("localhost",6380));      ShardedJedisPool pool = new ShardedJedisPool(new JedisPoolConfig(), shards);      ShardedJedis one = pool.getResource();      ShardedJedisPipeline pipeline = one.pipelined();      long start = System.currentTimeMillis();     for (int i = 0; i < 100000; i++) {         pipeline.set("sppn" + i, "n" + i);     }     List<Object> results = pipeline.syncAndReturnAll();     long end = System.currentTimeMillis();     pool.returnResource(one);     System.out.println("Pipelined@Pool SET: " + ((end - start)/1000.0) + " seconds");     pool.destroy(); }

    九、需要注意的地方

    1. 事務和管道都是異步模式。在事務和管道中不能同步查詢結果。比如下面兩個調用,都是不允許的:

       Transaction tx = jedis.multi();  for (int i = 0; i < 100000; i++) {      tx.set("t" + i, "t" + i);  }  System.out.println(tx.get("t1000").get());  //不允許   List<Object> results = tx.exec();   …  …   Pipeline pipeline = jedis.pipelined();  long start = System.currentTimeMillis();  for (int i = 0; i < 100000; i++) {      pipeline.set("p" + i, "p" + i);  }  System.out.println(pipeline.get("p1000").get()); //不允許   List<Object> results = pipeline.syncAndReturnAll();
    2. 事務和管道都是異步的,個人感覺,在管道中再進行事務調用,沒有必要,不如直接進行事務模式。

    3. 分布式中,連接池的性能比直連的性能略好(見后續測試部分)。

    4. 分布式調用中不支持事務。

      因為事務是在服務器端實現,而在分布式中,每批次的調用對象都可能訪問不同的機器,所以,沒法進行事務。

    十、測試

    運行上面的代碼,進行測試,其結果如下:

    Simple SET: 5.227 seconds  Transaction SET: 0.5 seconds Pipelined SET: 0.353 seconds Pipelined transaction: 0.509 seconds  Simple@Sharing SET: 5.289 seconds Pipelined@Sharing SET: 0.348 seconds  Simple@Pool SET: 5.039 seconds Pipelined@Pool SET: 0.401 seconds

    另外,經測試分布式中用到的機器越多,調用會越慢。上面是2片,下面是5片:

    Simple@Sharing SET: 5.494 seconds Pipelined@Sharing SET: 0.51 seconds Simple@Pool SET: 5.223 seconds Pipelined@Pool SET: 0.518 seconds

    下面是10片:

    Simple@Sharing SET: 5.9 seconds Pipelined@Sharing SET: 0.794 seconds Simple@Pool SET: 5.624 seconds Pipelined@Pool SET: 0.762 seconds

    下面是100片:

    Simple@Sharing SET: 14.055 seconds Pipelined@Sharing SET: 8.185 seconds Simple@Pool SET: 13.29 seconds Pipelined@Pool SET: 7.767 seconds

    分布式中,連接池方式調用不但線程安全外,根據上面的測試數據,也可以看出連接池比直連的效率更好。

    十一、完整的測試代碼

    package com.example.nosqlclient;  import java.util.Arrays; import java.util.List;  import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test;  import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.Pipeline; import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedisPipeline; import redis.clients.jedis.ShardedJedisPool; import redis.clients.jedis.Transaction;  import org.junit.FixMethodOrder; import org.junit.runners.MethodSorters;  @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestJedis {      private static Jedis jedis;     private static ShardedJedis sharding;     private static ShardedJedisPool pool;      @BeforeClass     public static void setUpBeforeClass() throws Exception {         List<JedisShardInfo> shards = Arrays.asList(                 new JedisShardInfo("localhost",6379),                 new JedisShardInfo("localhost",6379)); //使用相同的ip:port,僅作測試           jedis = new Jedis("localhost");          sharding = new ShardedJedis(shards);          pool = new ShardedJedisPool(new JedisPoolConfig(), shards);     }      @AfterClass     public static void tearDownAfterClass() throws Exception {         jedis.disconnect();         sharding.disconnect();         pool.destroy();     }      @Test     public void test1Normal() {         long start = System.currentTimeMillis();         for (int i = 0; i < 100000; i++) {             String result = jedis.set("n" + i, "n" + i);         }         long end = System.currentTimeMillis();         System.out.println("Simple SET: " + ((end - start)/1000.0) + " seconds");     }      @Test     public void test2Trans() {         long start = System.currentTimeMillis();         Transaction tx = jedis.multi();         for (int i = 0; i < 100000; i++) {             tx.set("t" + i, "t" + i);         }         //System.out.println(tx.get("t1000").get());          List<Object> results = tx.exec();         long end = System.currentTimeMillis();         System.out.println("Transaction SET: " + ((end - start)/1000.0) + " seconds");     }      @Test     public void test3Pipelined() {         Pipeline pipeline = jedis.pipelined();         long start = System.currentTimeMillis();         for (int i = 0; i < 100000; i++) {             pipeline.set("p" + i, "p" + i);         }         //System.out.println(pipeline.get("p1000").get());         List<Object> results = pipeline.syncAndReturnAll();         long end = System.currentTimeMillis();         System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds");     }      @Test     public void test4combPipelineTrans() {         long start = System.currentTimeMillis();         Pipeline pipeline = jedis.pipelined();         pipeline.multi();         for (int i = 0; i < 100000; i++) {             pipeline.set("" + i, "" + i);         }         pipeline.exec();         List<Object> results = pipeline.syncAndReturnAll();         long end = System.currentTimeMillis();         System.out.println("Pipelined transaction: " + ((end - start)/1000.0) + " seconds");     }      @Test     public void test5shardNormal() {         long start = System.currentTimeMillis();         for (int i = 0; i < 100000; i++) {             String result = sharding.set("sn" + i, "n" + i);         }         long end = System.currentTimeMillis();         System.out.println("Simple@Sharing SET: " + ((end - start)/1000.0) + " seconds");     }      @Test     public void test6shardpipelined() {         ShardedJedisPipeline pipeline = sharding.pipelined();         long start = System.currentTimeMillis();         for (int i = 0; i < 100000; i++) {             pipeline.set("sp" + i, "p" + i);         }         List<Object> results = pipeline.syncAndReturnAll();         long end = System.currentTimeMillis();         System.out.println("Pipelined@Sharing SET: " + ((end - start)/1000.0) + " seconds");     }      @Test     public void test7shardSimplePool() {         ShardedJedis one = pool.getResource();          long start = System.currentTimeMillis();         for (int i = 0; i < 100000; i++) {             String result = one.set("spn" + i, "n" + i);         }         long end = System.currentTimeMillis();         pool.returnResource(one);         System.out.println("Simple@Pool SET: " + ((end - start)/1000.0) + " seconds");     }      @Test     public void test8shardPipelinedPool() {         ShardedJedis one = pool.getResource();          ShardedJedisPipeline pipeline = one.pipelined();          long start = System.currentTimeMillis();         for (int i = 0; i < 100000; i++) {             pipeline.set("sppn" + i, "n" + i);         }         List<Object> results = pipeline.syncAndReturnAll();         long end = System.currentTimeMillis();         pool.returnResource(one);         System.out.println("Pipelined@Pool SET: " + ((end - start)/1000.0) + " seconds");     } }

    posted on 2014-09-11 20:33 paulwong 閱讀(458) 評論(0)  編輯  收藏 所屬分類: REDIS

    主站蜘蛛池模板: 亚洲高清成人一区二区三区| 亚洲人成网站免费播放| 青娱乐在线免费观看视频| 亚洲Av熟妇高潮30p| 最近2019年免费中文字幕高清| 美女被免费视频网站a| 亚洲国产视频网站| 亚洲av无码一区二区三区乱子伦 | 毛片免费视频观看| 精品亚洲国产成人| 国产jizzjizz免费看jizz| 999任你躁在线精品免费不卡| 亚洲午夜在线播放| 亚洲高清不卡视频| 成人免费视频软件网站| 100部毛片免费全部播放完整| 亚洲精品美女久久久久久久| 亚洲成人一级电影| 亚洲成年轻人电影网站www| 亚洲线精品一区二区三区| 免费成人av电影| 国产免费人成在线视频| 好男人视频在线观看免费看片| 一区二区三区在线观看免费| 日产亚洲一区二区三区| 国产做床爱无遮挡免费视频| 国产一卡2卡3卡4卡无卡免费视频| 99re视频精品全部免费| 免费福利电影在线观看| 中文字幕日本人妻久久久免费| a毛片在线免费观看| 亚洲av无码一区二区三区天堂| 亚洲国产精品综合久久20| 亚洲国产成人精品电影| 亚洲综合熟女久久久30p| 亚洲精品国产高清嫩草影院| 国产在线观看片a免费观看| 日韩免费一区二区三区在线 | 又黄又爽一线毛片免费观看| 国产极品粉嫩泬免费观看| 国产成人免费一区二区三区|