前提:首先我们得区分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 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);
}
}