Jedis分片 redis
動機
在普通的Redis主/從方式,一般有一個主服務器負責"write"請求,多個從服務器負責"read"請求。這就意味着用戶必須當心有效的處理從服務器的負載分配。此外,只是"read"請求被分配到多個從服務器上,可是"write"請求沒有,由於極可能只有一個主服務器。對於Jedis分片能夠實現"read""write"兩方面擴展性。分片使用的技術是"一致性哈希",根據一些哈希算法分配一些key.一個節點被叫作"片".更進一步的優點是每一個片只須要有總數據集的1/n的內存. (n是加入從服務器的數目).
缺點
由於每一個片是單獨的主服務器,分片有一些限制的功能:例如,不能使用事務,pipelining,發佈/訂閱。然而,一般這些不容許的操做是可行的,只要關心keys在一個相同的片。更進一步的缺點是當前標準實現,在運行中的ShardedJedis不能添加或者移除片。若是須要這個特性,須要重現實現ShardedJedis,容許在一個運行ShardedJedis動態的添加和移除片: yaourt - dynamic sharding implementation 算法
1.定義分片 服務器
1 |
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); |
2 |
JedisShardInfo si = new JedisShardInfo("localhost", 6379); |
3 |
si.setPassword("foobared"); |
5 |
si = new JedisShardInfo("localhost", 6380); |
6 |
si.setPassword("foobared"); |
有兩種方式使用ShardedJedis.直接鏈接或者使用ShardedJedisPool.後者須要在多線程環境下使用。 網絡
2.a)直接鏈接: 多線程
1 |
ShardedJedis jedis = new ShardedJedis(shards); |
2.b) 鏈接池:
01 |
ShardedJedisPool pool = new ShardedJedisPool(new Config(), shards); |
02 |
ShardedJedis jedis = pool.getResource(); |
03 |
jedis.set("a", "foo"); |
04 |
.... // do your work here |
05 |
pool.returnResource(jedis); |
06 |
.... // a few moments later |
07 |
ShardedJedis jedis2 = pool.getResource(); |
08 |
jedis.set("z", "bar"); |
09 |
pool.returnResource(jedis); |
3.Disconnect / returnRessource 性能
在某一特定時刻完成使用Jedis儘快調用pool.returnResource。若是不這樣作,鏈接池在一段時間後會變慢。getResource和returnResource的速度很快,沒有鏈接了必需要建立。鏈接池的建立和銷燬是比較慢的,由於這樣鏈接其實是網絡鏈接。忘記pool.destroy保持鏈接始終打開直接過時. spa
肯定某個鍵的片的信息 .net
1 |
ShardInfo si = jedis.getShardInfo(key); |
2 |
si.getHost/getPort/getPassword/getTimeout/getName |
肯定某些鍵去相同的片 線程
實現這個目標須要的是"keytags"。使用keytags只須要在實例化ShardedJedis時設置一個模式。例如: blog
1 |
ShardedJedis jedis = new ShardedJedis(shards, |
2 |
ShardedJedis.DEFAULT_KEY_TAG_PATTERN); |
能夠建立本身的模式。默認的模式是{},不管大括號裏是什麼將被用來肯定分片。
例如:
1 |
jedis.set("foo{bar}", "12345"); |
3 |
jedis.set("car{bar}", "877878"); |
將去相同的片.
混合的方法
若是想更容易的加載分佈的ShardedJedis,可是仍然須要事務/pipelining/發佈訂閱等,能夠混合普通reids服務器和分片的redis服務器的方法:定義一個master做爲普通的Jedis,其餘的做爲分片Jedis.使全部的分片redis服務器slaveof以前的master。"write"請求直接到master,"read"請求到ShardedJedis。"write"請求沒有任何的擴展,可是"read"請求提升了很好的分佈性,事務/pipelining/發佈訂閱等操做只用於master.數據集應該適合master的內存。若是讓slaves作持久化的工做能夠使master提升不少的性能。
參考:
http://blog.csdn.net/xiaolang85/article/details/12655507
http://blog.csdn.net/xiaolang85/article/details/12655519