Redis學習筆記11--Redis分布式

來源:互聯網
上載者:User

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++);

    }

}

從運行結果中可以看到,不同的key被分配到不同的Redis-Server上去了。

 

       實際上,上面的叢集模式還存在兩個問題:

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本身的複製功能的,如果主庫快照資料檔案過大,這個複製的過程也會很久,同時會給主庫帶來壓力。所以做這個拆分的過程最好選擇為業務訪問低峰時段進行。

http://blog.nosqlfan.com/html/3153.html

 

2.       單點故障問題:

還是用到Redis主從複製的功能,兩台物理主機上分別都運行有Redis-Server,其中一個Redis-Server是另一個的從庫,採用雙機熱備技術,用戶端通過虛擬IP訪問主庫的物理IP,當主庫宕機時,切換到從庫的物理IP。只是事後修複主庫時,應該將之前的從庫改為主庫(使用命令slaveof no one),主庫變為其從庫(使命令slaveof IP PORT),這樣才能保證修複期間新增資料的一致性。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.