Redis集羣

1.集羣:多個服務器集中在一塊兒,實現同一個業務,當一臺服務器不能知足開發需求的時候,須要多臺服務器的支持,這時就須要作集羣,可是集羣每每伴隨着分佈式.

分佈式服務之間的相互通訊:RPC方案,遠程調用框架
分佈式的缺點:事務和緩存的處理問題
2.集羣和分佈式概述前端

a)  分佈式:將不一樣的業務分佈在不一樣的服務器,web應用和 數據庫服務分開node

  1. 集羣分類

a)  數據庫集羣,應用集羣,功能集羣,Tomcat集羣web

  1. 集羣的兩大特性

a)  可擴展性redis

            i.     能夠動態的添加新的服務器,加強集羣的性能算法

b)  高可用性數據庫

            i.     集羣經過服務實體冗餘使客戶端免於輕易遇到out of service的警告。在集羣中,一樣的服務能夠由多個服務實體提供。若是一個服務實體失敗了,另外一個服務實體會接管失敗的服務實體。集羣提供的從一個出錯的服務實體恢復到另外一個服務實體的功能加強了應用的可用性,當訪問的服務器掛了時,集羣要有能力找能夠正常使用額服務器繼續提供服務器。緩存

  1. 集羣的兩大能力

a)  負載均衡ruby

            i.     負載均衡能把任務比較均衡地分佈到集羣環境下的計算和網絡資源。服務器

           ii.     負載均衡的策略:輪詢,權重,隨機網絡

b)  錯誤恢復

            i.     因爲某種緣由,執行某個任務的資源出現故障,另外一服務實體中執行同一任務的資源接着完成任務。這種因爲一個實體中的資源不能工做,另外一個實體中的資源透明的繼續完成任務的過程叫錯誤恢復。當訪問的服務器掛了時,集羣要有能力找能夠正常使用額服務器繼續提供服務器.

           ii.     注意: 負載均衡和錯誤恢復都要求各服務實體中有執行同一任務的資源存在,並且對於同一任務的各個資源來講,執行任務所需的信息視圖(信息上下文)必須是同樣的

         iii.     集羣和分佈式的相同點和不一樣點

  1. 相同點:都是用來處理高併發的,須要多臺服務器的支持,( 通常在一個系統中同時存在分佈式和集羣.)
  2. 不一樣點:分佈式中不一樣的服務器處理不一樣的業務,而集羣是多個服務器處理同一個業務.



  3. Redis集羣方案的選擇

a)  爲何選擇使用Redis作集羣

            i.     Redis集羣可防止單點故障

           ii.     處理高併發問題

         iii.     處理大量數據,數據太多,一臺服務器的內存搞不定

b)  Redis集羣方案一:主從複製,主機或者從掛了就會有數據的丟失

            i.     原理:

從服務器鏈接主服務器,發送SYNC命令;

主服務器接收到SYNC命名後,開始執行BGSAVE命令生成RDB文件並使用緩衝區記錄此後執行的全部寫命令;

主服務器BGSAVE執行完後,向全部從服務器發送快照文件,並在發送期間繼續記錄被執行的寫命令;

從服務器收到快照文件後丟棄全部舊數據,載入收到的快照;

主服務器快照發送完畢後開始向從服務器發送緩衝區中的寫命令;

從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩衝區的寫命令;(從服務器初始化完成)主服務器每執行一個寫命令就會向從服務器發送相同的寫命令,從服務器接收並執行收到的寫命令(從服務器初始化完成後的操做)

                  ii.      主從同步,讀寫分離

好處:主服務器向從服務器複製數據,從服務器用來進行讀的操做,主服務器用來進行寫的操做,這樣可減少對主服務器的讀的操做的壓力

壞處: Redis不具有自動容錯和恢復功能,主機從機的宕機都會致使前端部分讀寫請求失敗,須要等待機器重啓或者手動切換前端的IP才能恢復。

主機宕機,宕機前有部分數據未能及時同步到從機,切換IP後還會引入數據不一致的問題,下降了系統的可用性。Redis較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜。只解決高併發.

a)  Redis集羣方案二:Redis-Cluster集羣

a)  從redis 3.0以後版本支持redis-cluster集羣,它是Redis官方提出的解決方案,Redis-Cluster採用無中心結構,每一個節點保存數據和整個集羣狀態,每一個節點都和其餘全部節點鏈接。其redis-cluster架構圖以下:

 

 

 

客戶端與 redis 節點直連,不須要中間 proxy 層.客戶端不須要鏈接集羣全部節點鏈接集羣中任何一個可用節點便可。

b)  全部的 redis 節點彼此互聯(PING-PONG 機制),內部使用二進制協議優化傳輸速度和帶寬.

c)  每一個Redis服務的節點上都存儲不一樣的內容,也包含主節點和從節點,主節點掛了,從節點填充上去,解決單點故障

                 i.     每一個節點裏面都有一個插槽,經過一種算法來存儲數據,還有一個cluster插件, 當咱們的存取的key到達的時候,redis會根據crc16的算法得出一個結果,而後把結果對 16384 求餘數,這樣每一個 key 都會對應一個編號在 0-16383 之間的哈希槽,經過這個值,去找到對應的插槽所對應的節點,而後直接自動跳轉到這個對應的節點上進行存取操做。爲了保證高可用,redis-cluster集羣引入了主從模式,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啓用從節點。當其它主節點ping一個主節點A時,若是半數以上的主節點與A通訊超時,那麼認爲主節點A宕機了。若是主節點A和它的從節點A1都宕機了,那麼該集羣就沒法再提供服務了。

b)  集羣方案三:哨兵模式

a)  當主服務器掛掉以後,咱們能夠進行手動配置將從服務器自動設置升級爲主服務器.

b)       優勢:

哨兵模式是基於主從模式的,全部主從的優勢,哨兵模式都具備。

主從能夠自動切換,系統更健壯,可用性更高。

c)        缺點:

Redis較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜

d)   

7.集羣環境的搭建(這裏對方案二集羣環境搭建的介紹)

   a) 需求:六臺Redis的服務器,僞集羣

   b)  六個Redis的服務器實例和六個Redis的端口

   c) ruby語言運行環境的搭建,ruby腳原本實現集羣搭建,先安裝ruby腳本運行環境,再安裝(rubyGems)的驅動rubygems,

   d) rubyGems安裝完畢以後,cmd運行setup.rb

   e) 再用rubyGems安裝Redis(命令: gem install redis)

f)      啓動每一個Redis服務,將redis-trib.rb文件拷貝到其中一個Redis節點裏面
                  執行命令

 redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384

輸入yes回車命令

看集羣是否配置成功.

8.Redis集羣環境的測試

         a)命令行測試Redis-cli

使用Redis客戶端Redis-cli.exe來查看數據記錄數,以及集羣相關信息

命令 redis-cli –c –h 」地址」 –p "端口號" ;  c 表示集羣

 

         b) 查看集羣的信息,命令:cluster info

         c)  查看主從服務器命令

                  先用命令 redis-cli –c –h 」地址」 –p "端口號" 找到集羣

                  而後運行info replication查看是主服務器仍是從服務器.

         d)     存值測試

9.Jedis代碼測試Redis集羣是否集成完畢

@Test

    public void testCluster() throws IOException, InterruptedException {

        Set<HostAndPort> nodes = new HashSet<>();

        nodes.add(new HostAndPort("127.0.0.1", 6379));

        nodes.add(new HostAndPort("127.0.0.1", 6380));

        nodes.add(new HostAndPort("127.0.0.1", 6381));

        nodes.add(new HostAndPort("127.0.0.1", 6382));

        nodes.add(new HostAndPort("127.0.0.1", 6383));

        nodes.add(new HostAndPort("127.0.0.1", 6384));

        JedisCluster cluster = new JedisCluster(nodes);

        try {

            String res = cluster.get("key值");

            System.out.println(res);

//            cluster.quit();

        } catch (Exception e) {

            e.printStackTrace();

//            cluster.quit();

        }

    }

}

相關文章
相關標籤/搜索