Redis集羣與分佈式介紹以及搭建Redis-Cluster

1 Redis集羣

1.1 什麼是集羣

集羣就是不少服務器組成的一個網絡。指的是將多臺服務器集中在一塊兒,實現同一業務前端

1.2 爲何要集羣

一臺服務器不能知足開發須要的時候,須要多臺服務器來支持。這個時候就須要作集羣,可是集羣每每伴隨java

着分佈式。node

1.3 集羣的特性及能力

一、集羣的兩大關鍵特性:web

可擴展性----集羣的性能不限於單一的服務實體,新的服務實體能夠動態地加入到集羣,從而加強集羣的性能。動態添加服務器
高可用性----集羣經過服務實體冗餘使客戶端免於輕易遇到out of service的警告。在集羣中,一樣的服務能夠由多個服務實體提供。若是一個服務實體失敗了,另外一個服務實體會接管失敗的服務實體。集羣提供的從一個出錯的服務實體恢復到另外一個服務實體的功能加強了應用的可用性
二、集羣的兩大能力:redis

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

錯誤恢復----因爲某種緣由,執行某個任務的資源出現故障,另外一服務實體中執行同一任務的資源接着完成任務。這種因爲一個實體中的資源不能工做,另外一個實體中的資源透明的繼續完成任務的過程叫錯誤恢復。數據庫

2 分佈式

分佈式是將不一樣的業務分佈在不一樣的地方,web應用和數據庫服務分開,將不一樣業務分不到不一樣的集羣。windows

分佈式的特色:ruby

  1. 防止單點故障服務器

  2. 處理高併發(太多請求,一臺服務器搞不定)

  3. 處理大量數據(太多內存數據,一臺服務器處理不過來)

3 Redis集羣的方案

3.1 主從複製

主從同步,讀寫分離,主備切換。

原理:

  • 從服務器鏈接主服務器,發送SYNC命令;
  • 主服務器接收到SYNC命名後,開始執行BGSAVE命令生成RDB文件並使用緩衝區記錄此後執行的全部寫命令;
  • 主服務器BGSAVE執行完後,向全部從服務器發送快照文件,並在發送期間繼續記錄被執行的寫命令;
  • 從服務器收到快照文件後丟棄全部舊數據,載入收到的快照;
  • 主服務器快照發送完畢後開始向從服務器發送緩衝區中的寫命令;
  • 從服務器完成對快照的載入,開始接收命令請求,並執行來自主服務器緩衝區的寫命令;(從服務器初始化完成)
  • 主服務器每執行一個寫命令就會向從服務器發送相同的寫命令,從服務器接收並執行收到的寫命令(從服務器初始化完成後的操做)

優勢:

  • 支持主從複製,主機會自動將數據同步到從機,能夠進行讀寫分離

缺點:

  • Redis較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜。
  • Redis不具有自動容錯和恢復功能,主機從機的宕機都會致使前端部分讀寫請求失敗,須要等待機器重啓或者手動切換前端的IP才能恢復。
  • 主機宕機,宕機前有部分數據未能及時同步到從機,切換IP後還會引入數據不一致的問題,下降了系統的可用性。

3.2 哨兵模式

自動化的系統監控和故障恢復功能。

優勢:哨兵模式是基於主從模式的,全部主從的優勢,哨兵模式都具備。主從能夠自動切換,系統更健壯,可用性更高。

缺點:比較難擴容,服務佔用空間比較多

3.3 Redis-Cluster集羣

3.3.1 什麼是Redis-Cluster

Redis的哨兵模式基本已經能夠實現高可用,讀寫分離 ,可是在這種模式下每臺redis服務器都存儲相同的數據,很浪費內存,因此在redis3.0上加入了cluster模式,實現的redis的分佈式存儲,也就是說每臺redis節點上存儲不一樣的內容。

爲什麼要搭建Redis集羣。Redis是在內存中保存數據的,而咱們的電腦通常內存都不大,這也就意味着Redis不適合存儲大數據,適合存儲大數據的是Hadoop生態系統的Hbase或者是MogoDB。Redis更適合處理高併發,一臺設備的存儲能力是頗有限的,可是多臺設備協同合做,就可讓內存增大不少倍,這就須要用到集羣。

Redis集羣搭建的方式有多種,例如使用客戶端分片、Twemproxy、Codis等,但從redis 3.0以後版本支持redis-cluster集羣,它是Redis官方提出的解決方案,Redis-Cluster採用無中心結構,每一個節點保存數據和整個集羣狀態,每一個節點都和其餘全部節點鏈接。其redis-cluster架構圖以下:

 

 

 

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

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

3.3.2 分佈存儲機制—槽

redis-cluster 把全部的物理節點映射到[0-16383]slot 上,cluster 負責維護。

Redis 集羣中內置了 16384 個哈希槽,當須要在 Redis 集羣中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,而後把結果對 16384 求餘數,這樣每一個key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量大體均等的將哈希槽映射到不一樣的節點。

例如三個節點:槽分佈的值以下:

SERVER1: 0-5460

SERVER2: 5461-10922

SERVER3: 10923-16383

3.3.3 容錯機制—投票

1)選舉過程是集羣中全部master參與,若是半數以上master節點與故障節點通訊超過(cluster-node-timeout),認爲該節點故障,自動觸發故障轉移操做. 故障節點對應的從節點自動升級爲主節點

(2)何時整個集羣不可用(cluster_state:fail)?

若是集羣任意master掛掉,且當前master沒有slave.集羣進入fail狀態,也能夠理解成集羣的slot映射[0-16383]不完成時進入fail狀態。

 

 4 集成環境搭建

4.1 準備工做

(1)Redis 3.2

須要 6 臺 redis 服務器。搭建僞集羣。

須要 6 個 redis 實例。

須要運行在不一樣的端口 6379-6384

(2)Ruby語言運行環境 咱們須要使用ruby腳原本實現集羣搭建

Ruby,一種簡單快捷的面向對象(面向對象程序設計)腳本語言,在20世紀90年代由日本人松本行弘(Yukihiro Matsumoto)開發,遵照GPL協議和Ruby License。它的靈感與特性來自於 Perl、Smalltalk、Eiffel、Ada以及 Lisp 語言。由 Ruby 語言自己還發展出了JRuby(Java平臺)、IronRuby(.NET平臺)等其餘平臺的 Ruby 語言替代品。Ruby的做者於1993年2月24日開始編寫Ruby,直至1995年12月才正式公開發佈於fj(新聞組)。由於Perl發音與6月誕生石pearl(珍珠)相同,所以Ruby以7月誕生石ruby(紅寶石)命名。

(3)RubyGems簡稱gems,是一個用於對 Ruby組件進行打包的 Ruby 打包系統

(4)Redis的Ruby驅動redis-xxxx.gem

(5)建立Redis集羣的工具redis-trib.rb

4.2 開始搭建

(1)拷貝6個服務器,並將其端口號依次改成637九、6380、638一、638二、638三、6384.

(2)在redis.windows.conf配置文件中設置如下屬性:

cluster-enabled yes

cluster-config-file nodes-6379.conf

cluster-node-timeout 15000

appendonly yes

(3)編寫啓動腳本startup.bat,內容爲:

title redis-6379

redis-server.exe redis.windows.conf

(4)安裝Ruby,redis的集羣須要使用。

(5)安裝Redis的Rudy驅動redis-xxxx.gem

下載地址:Rubygems官方下載地址

下載zip文件,下載後解壓。當前目錄切換到解壓目錄中,如 D:\redis-cluster\rubygems-3.0.6\rubygems-3.0.6而後命令行執行 ruby setup.rb

再用 GEM 安裝 Redis :切換到redis安裝目錄,須要在命令行中,執行 gem install redis

 

 

 (6)啓動每一個節點並執行集羣構建腳本,點擊每一個節點start.bat進行啓動,拷貝redis-trib.rb到6379的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

在出現 Can I set the above configuration? (type ‘yes’ to accept): 請肯定並輸入 yes 。

4.3 集羣環境測試

4.3.1 命令測試

  • redis-cli –c –h 」地址」 –p 「端口號」 ; c 表示集羣
  • cluster info 查看集羣的信息
  • info replication 查看當前服務器的信息
  • cluster nodes 查看各個節點分配slot

4.3.2 java代碼測試

@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("name");
            System.out.println(res);
//            cluster.quit();
        } catch (Exception e) {
            e.printStackTrace();
//            cluster.quit();
        }
    }
}

1.1.1.   分佈存儲機制-

相關文章
相關標籤/搜索