public class RedisShardPoolTest {
static ShardedJedisPool pool;
static {
JedisPoolConfig config = new JedisPoolConfig();// Jedis池配置
config.setMaxActive(500);// 最大活動的對象個數
config.setMaxIdle(1000 * 60);// 對象最大空閒時間
config.setMaxWait(1000 * 10);// 獲取對象時最大等待時間
config.setTestOnBorrow(true);
String hostA = "127.0.0.1";
int portA = 6378;
String hostB = "127.0.0.1";
int portB = 6379;
List<JedisShardInfo> jdsInfoList = new ArrayList<JedisShardInfo>(2);
JedisShardInfo infoA = new JedisShardInfo(hostA, portA);
infoA.setPassword("testpass");
JedisShardInfo infoB = new JedisShardInfo(hostB, portB);
infoB.setPassword("testpass");
jdsInfoList.add(infoA);
jdsInfoList.add(infoB);
pool = new ShardedJedisPool(config, jdsInfoList, Hashing.MURMUR_HASH,
Sharded.DEFAULT_KEY_TAG_PATTERN);
}
/**
*
* @param args
*
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
String key = generateKey();
ShardedJedis jds = null;
try {
jds = pool.getResource();
System.out.println(key + ":"
+ jds.getShard(key).getClient().getHost());
System.out.println(key + ":"
+ jds.getShard(key).getClient().getPort());
System.out.println(jds.get(key));
System.out.println(jds.set(key,"1111111111111111111111111111111"));
} catch (Exception e) {
e.printStackTrace();
}
finally {
pool.returnResource(jds);
}
}
}
private static int index = 1;
public static String generateKey() {
return String.valueOf(Thread.currentThread().getId()) + "_" + (index++);
}
}
從運行結果中能夠看到,不一樣的key被分配到不一樣的Redis-Server上去了。web
上面的集羣模式還存在兩個問題:
1.
擴容問題:
由於使用了一致性哈稀進行分片,那麼不一樣的key
分佈到不一樣的Redis-Server
上,當咱們須要擴容時,須要增長機器到分片列表中,這時候會使得一樣的key
算出來落到跟原來不一樣的機器上,這樣若是要取某一個值,會出現取不到的狀況,對於這種狀況,Redis
的做者提出了一種名爲Pre-Sharding
的方式:
Pre-Sharding
方法是將每個臺物理機上,運行多個不一樣斷口的Redis
實例,假若有三個物理機,每一個物理機運行三個Redis
實際,那麼咱們的分片列表中實際有9
個Redis
實例,當咱們須要擴容時,增長一臺物理機,步驟以下:
A.
在新的物理機上運行Redis-Server
;
B.
該Redis-Server
從屬於(slaveof)
分片列表中的某一Redis-Server
(假設叫RedisA
);
C.
等主從複製(Replication)
完成後,將客戶端分片列表中RedisA
的IP
和端口改成新物理機上Redis-Server
的IP
和端口;
D.
中止RedisA
。
這樣至關於將某一Redis-Server
轉移到了一臺新機器上。Prd-Sharding
其實是一種在線擴容的辦法,但仍是很依賴Redis
自己的複製功能的,若是主庫快照數據文件過大,這個複製的過程也會好久,同時會給主庫帶來壓力。因此作這個拆分的過程最好選擇爲業務訪問低峯時段進行。
2.
單點故障問題:
仍是用到Redis
主從複製的功能,兩臺物理主機上分別都運行有Redis-Server
,其中一個Redis-Server
是另外一個的從庫,採用雙機熱備技術,客戶端經過虛擬IP
訪問主庫的物理IP
,當主庫宕機時,切換到從庫的物理IP
。只是過後修復主庫時,應該將以前的從庫改成主庫(使用命令slaveofno one
),主庫變爲其從庫(使命令slaveofIP PORT
),這樣才能保證修復期間新增數據的一致性
最終部署的狀況會是,分佈式的每臺server
會有一個對應的備機(從機),這樣即便有一個分佈式的片機掛掉,對應的備機會接管,不會致使由於片機掛掉致使部分數據不能寫進或取出的問題
附件是一份windows下redis服務端程序和客戶端須要的jar包,附件下載後後綴改成.rar後解壓縮
能夠本身配置分佈式和主從測試,
配置文件着重關注如下配置
服務端口和 綁定網卡IP
# Accept connections on the specified port, default is 6379
port 6178
# If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for connections.
#
# bind 127.0.0.1
是否爲備機(IP:端口)
################################# REPLICATION #################################
# Master-Slave replication. Use slaveof to make a Redis instance a copy of
# another Redis server. Note that the configuration is local to the slave
# so for example it is possible to configure the slave to save the DB with a
# different interval, or to listen to another port, and so on.
#
slaveof 127.0.0.1 6378
認證密碼
# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the slave to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the slave request.
#
最好深讀官方的解決方案http://redis.io/topics/partitioningredis