1. 程式人生 > >redis客戶端之jedis和sharedJedis

redis客戶端之jedis和sharedJedis

前提:首先我們得區分2.x和3.x版本,因為3.x版本開始支援redis叢集

問題:那麼在2.x怎麼進行redis伺服器擴充套件

解決方式:橫向擴充套件(多個相互獨立的主從伺服器群)

伺服器搭建在此不進行敘述

那麼問題又來了,jedis在未叢集的情況下只能操作單redis伺服器,jedis客戶端怎麼對橫向擴充套件的伺服器群進行資料操作

解決方式:使用SharedJedis來實現分散式快取,ShardedJedis通過一致性雜湊來實現分散式快取的,通過一定的策略把不同的key分配到不同的redis server上,達到橫向擴充套件的目

ShardedJedis的使用方法和Jedis類似

區別: ShardedJedis不支援多命令操作,像mget、mset、brpop等可以在redis命令後一次性操作多個key的命令,具體jedis命令可參照Jedis下的 MultiKeyCommands 類,包含了所有的多命令操作。這些多操作命令已經在SharedJedis中過濾掉

SharedJedis客戶端建立

//設定連線池的相關配置
        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();
          }
        }
 
 
        try(ShardedJedis jedis = jedisPool.getResource()) {
            jedis.set("test", "test");
            jedis.set("test1", "test1");
            String test = jedis.get("test");
            System.out.println(test);
        }

從程式碼上看,除了初始化ShardedJedisPool時需要加入多個Redis伺服器資訊,其他的和Jedis使用差不多。

在初始化ShardedJedisPool 時,還可以傳入ShardedJedis採用的hash演算法,支援MURMUR_HASH 和MD5兩種演算法,預設是使用MURMUR_HASH(可以檢視redis.clients.util.Hashing 類檢視相關的資訊)

另外還可以傳入keyTagPattern來指定我們key的分佈策略,所有能夠匹配keyTagPattern的key(通過正則匹配)將放在同一個redis裡,預設的是直接使用key來進行判定。Redis自帶了一個Sharded.keyTagPattern,如下

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());

輸出結果:cnblog和redis在同一個redis server中,另外兩個分別在另外的redis server中  

jedis客戶端建立

jedis客戶端工具類

public class JedisPoolUtil {
  
  private static volatile JedisPool jedisPool = null;
  
  private JedisPoolUtil() {}
  
  public static JedisPool getJedisPoolInstance()
  {
     if(null == jedisPool)
     {
       synchronized (JedisPoolUtil.class)
       {
          if(null == jedisPool)
          {
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            poolConfig.setMaxActive(1000);
            poolConfig.setMaxIdle(32);
            poolConfig.setMaxWait(100*1000);
            poolConfig.setTestOnBorrow(true);
            
            jedisPool = new JedisPool(poolConfig,"127.0.0.1");
          }
       }
     }
     return jedisPool;
  }
  
  public static void release(JedisPool jedisPool,Jedis jedis)
  {
     if(null != jedis)
     {
       jedisPool.returnResourceObject(jedis);
     }
  }
}

根據工具類獲取客戶端

public static void main(String[] args) {
     JedisPool jedisPool = JedisPoolUtil.getJedisPoolInstance();
     Jedis jedis = null;
     
     try 
     {
       jedis = jedisPool.getResource();
       jedis.set("k18","v183");
       
     } catch (Exception e) {
       e.printStackTrace();
     }finally{
       JedisPoolUtil.release(jedisPool, jedis);
     }
  }