Jedis下的ShardedJedis(分佈式)使用方法(一)

原來項目中有用到Redis用做緩存服務,剛開始時只用一臺Redis就可以知足服務,隨着項目的慢慢進行,發現一臺知足不了現有的項目需求,由於Redis操做都是原子性這樣的特性,形成有時同時讀寫緩存形成查詢效率的降低。可是因爲咱們如今用的仍是2.X版本,仍是沒有集羣功能的(Redis做者在3.0版本中已經加入了集羣功能), 所以只能使用2.x版本中自帶的一個叫作ShardedJedis的來實現分佈式緩存。redis

ShardedJedis是經過一致性哈希來實現分佈式緩存的,經過必定的策略把不一樣的key分配到不一樣的redis server上,達到橫向擴展的目的。那麼ShardedJedis內部是怎麼實現的呢,文章會慢慢講解。算法

 

 1.ShardedJedis使用方法

ShardedJedis的使用方法除了配置時有點區別,其餘和Jedis基本相似,有一點要注意的是 ShardedJedis不支持多命令操做,像mget、mset、brpop等能夠在redis命令後一次性操做多個key的命令,具體包括哪些,你們能夠看Jedis下的 MultiKeyCommands 這個類,這裏面就包含了全部的多命令操做。很貼心的是,Redis做者已經把這些命令從ShardedJedis過濾掉了,使用時也調用不了這些方法,你們知道下就好了。數據庫

好了,如今來看基本的使用緩存

 

複製代碼
  //設置鏈接池的相關配置 JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(2); poolConfig.setMaxIdle(1); poolConfig.setMaxWaitMillis(2000); poolConfig.setTestOnBorrow(false); poolConfig.setTestOnReturn(false); //設置Redis信息 String host = "127.0.0.1"; JedisShardInfo shardInfo1 = new JedisShardInfo(host, 6379, 500); shardInfo1.setPassword("test123"); JedisShardInfo shardInfo2 = new JedisShardInfo(host, 6380, 500); shardInfo2.setPassword("test123"); JedisShardInfo shardInfo3 = new JedisShardInfo(host, 6381, 500); shardInfo3.setPassword("test123"); //初始化ShardedJedisPool List<JedisShardInfo> infoList = Arrays.asList(shardInfo1, shardInfo2, shardInfo3); ShardedJedisPool jedisPool = new ShardedJedisPool(poolConfig, infoList); //進行查詢等其餘操做 ShardedJedis jedis = null; try { jedis = jedisPool.getResource();   jedis.set("test", "test");   jedis.set("test1", "test1"); String test = jedis.get("test"); System.out.println(test); ...... } finally { //使用後必定關閉,還給鏈接池
   if(jedis!=null) {
    jedis.close();
    } }
複製代碼

 

 

jedis獲取後必定要關閉,這和咱們使用數據庫鏈接池是同樣的,放在finally塊中保證jedis的關閉.服務器

ps:若是你們使用的jdk是1.7版本或者以上的話,可使用1.7加入的try-with-resources語句 分佈式

 

複製代碼
try(ShardedJedis jedis = jedisPool.getResource()) { jedis.set("test", "test"); jedis.set("test1", "test1"); String test = jedis.get("test"); System.out.println(test); }
複製代碼

 

try-with-resources的效果和咱們上面寫法是同樣的,只是jedis.close()語法它會幫咱們調用,它會默認調用咱們在try-with-resources語句中聲明的,實現了Closeable 接口的對象的close方法(像上面的ShardedJedis),咱們常常用到的數據庫鏈接Connection和一些輸入輸出流均可以使用這種方法。測試

 

 從代碼上看,除了初始化ShardedJedisPool時須要加入多個Redis服務器信息,其餘的和Jedis使用差很少。spa

在初始化ShardedJedisPool 時,咱們還能夠傳入ShardedJedis採用的hash算法,支持MURMUR_HASHMD5兩種算法,默認是使用MURMUR_HASH(能夠查看redis.clients.util.Hashing 類查看相關的信息)code

另外還能夠傳入keyTagPattern來指定咱們key的分佈策略,全部可以匹配keyTagPattern的key(經過正則匹配)將放在同一個redis裏,默認的是直接使用key來進行斷定。Redis自帶了一個Sharded.keyTagPattern,以下 server

 

Pattern DEFAULT_KEY_TAG_PATTERN = Pattern.compile("\\{(.+?)\\}");

 

咱們能夠用下面的代碼來實際測試下

複製代碼
ShardedJedis jedis = jedisPool.getResource();

jedis.set("cnblog", "cnblog"); jedis.set("redis", "redis"); jedis.set("test", "test"); jedis.set("123456", "1234567"); Client client1 = jedis.getShard("cnblog").getClient(); Client client2 = jedis.getShard("redis").getClient(); Client client3 = jedis.getShard("test").getClient(); Client client4 = jedis.getShard("123456").getClient(); ////打印key在哪一個server中 System.out.println("cnblog in server:" + client1.getHost() + " and port is:" + client1.getPort()); System.out.println("redis in server:" + client2.getHost() + " and port is:" + client2.getPort()); System.out.println("test in server:" + client3.getHost() + " and port is:" + client3.getPort()); System.out.println("123456 in server:" + client4.getHost() + " and port is:" + client4.getPort());
複製代碼

 

 

看輸出內容:

相關文章
相關標籤/搜索