Redis的cluster集羣

目前Redis 實現集羣的方法主要是採用一致性哈稀分片(Shard ),將不一樣的key 分配到不一樣的redis server 上,達到橫向擴展的目的。
對於一致性哈稀分片的算法,Jedis-2.0.0 已經提供了,下面是使用示例代碼(以ShardedJedisPool 爲例):
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

相關文章
相關標籤/搜索