参考自:http://blog.csdn.net/freebird_lb/article/details/7778999
引用该博文:
目前Redis实现集群的方法主要是采用一致性哈稀分片(Shard),将不同的key分配到不同的redis server上,达到横向扩展的目的。Redis-2.4.15目前没有提供集群的功能,Redis作者在博客中说将在3.0中实现集群机制。目前Redis实现集群的方法主要是采用一致性哈稀分片(Shard),将不同的key分配到不同的redis server上,达到横向扩展的目的。下面来介绍一种比较常用的分布式场景:
在读写操作比较均匀且实时性要求较高,可以用下图的分布式模式:
在读操作远远多于写操作时,可以用下图的分布式模式:
对于一致性哈稀分片的算法,Jedis-2.0.0已经提供了,下面是使用示例代码(以ShardedJedisPool为例):
博文上贴的代码:
package com.jd.redis.client;
import java.util.ArrayList;
import java.util.List;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.util.Hashing;
import redis.clients.util.Sharded;
publicclass RedisShardPoolTest {
static ShardedJedisPoolpool;
static{
JedisPoolConfig config =new JedisPoolConfig();//Jedis池配置
config.setMaxActive(500);//最大活动的对象个数
config.setMaxIdle(1000 * 60);//对象最大空闲时间
config.setMaxWait(1000 * 10);//获取对象时最大等待时间
config.setTestOnBorrow(true);
String hostA = "10.10.224.44";
int portA = 6379;
String hostB = "10.10.224.48";
int portB = 6379;
List<JedisShardInfo> jdsInfoList =new ArrayList<JedisShardInfo>(2);
JedisShardInfo infoA = new JedisShardInfo(hostA, portA);
infoA.setPassword("redis.360buy");
JedisShardInfo infoB = new JedisShardInfo(hostB, portB);
infoB.setPassword("redis.360buy");
jdsInfoList.add(infoA);
jdsInfoList.add(infoB);
pool =new ShardedJedisPool(config, jdsInfoList, Hashing.MURMUR_HASH,
Sharded.DEFAULT_KEY_TAG_PATTERN);
}
/**
* @param args
*/
publicstaticvoid main(String[] args) {
for(int i=0; i<100; i++){
String key = generateKey();
//key += "{aaa}";
ShardedJedis jds = null;
try {
jds = pool.getResource();
System.out.println(key+":"+jds.getShard(key).getClient().getHost());
System.out.println(jds.set(key,"1111111111111111111111111111111"));
} catch (Exception e) {
e.printStackTrace();
}
finally{
pool.returnResource(jds);
}
}
}
privatestaticintindex = 1;
publicstatic String generateKey(){
return String.valueOf(Thread.currentThread().getId())+"_"+(index++);
}
}
自己的实验代码:
遗留问题:不懂博文上贴的代码,为什么要在for语句里一直获取jedis,归还jedis?为什么先获取再读完所有的最后归还jedis?
实验下来的小结:
1.一致性Hash分片算法,会使得自动把不同的key分配到不同的redis-server上
2.实现方法,与未分片之前不同,两者具体连接池的实现不同,其余存取方式是一样的。
package com.danny.jedisUtil;
import java.util.ArrayList;
import java.util.List;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
public class JedisSharedPoolTest {
private static ShardedJedisPool pool = null;
private static void getSharedPool(){
if(pool == null){
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(2);
config.setMaxIdle(5);
config.setMaxWaitMillis(10000);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
String hostA = "127.0.0.1";
int portA = 6380;
String hostB = "127.0.0.1";
int portB = 6382;
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
JedisShardInfo infoA = new JedisShardInfo(hostA, portA);
JedisShardInfo infoB = new JedisShardInfo(hostB, portB);
shards.add(infoA);
shards.add(infoB);
pool = new ShardedJedisPool(config, shards);
}
}
public static void main(String[] args){
getSharedPool();
ShardedJedis jedis = null;
ShardedJedis jedis2 = null;
//ShardedJedis jedis3 = null;
/*
try{
jedis = pool.getResource();
System.out.println(jedis.get("n0"));
System.out.println(jedis.get("n4"));
} catch (Exception e) {
e.printStackTrace();
}
finally{
pool.returnResource(jedis);
}
*/
try{
jedis = pool.getResource();
jedis2 = pool.getResource();
//jedis3 = pool.getResource();
for(int i = 0; i < 10; i++){
String key = "n" + i;
System.out.println(jedis.set(key, i+""));
}
}
catch (Exception e) {
e.printStackTrace();
}
finally{
pool.returnResource(jedis);
}
}
}