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