集羣就是不少服務器組成的一個網絡。指的是將多臺服務器集中在一塊兒,實現同一業務。前端
一臺服務器不能知足開發須要的時候,須要多臺服務器來支持。這個時候就須要作集羣,可是集羣每每伴隨java
着分佈式。node
一、集羣的兩大關鍵特性:web
可擴展性----集羣的性能不限於單一的服務實體,新的服務實體能夠動態地加入到集羣,從而加強集羣的性能。動態添加服務器
高可用性----集羣經過服務實體冗餘使客戶端免於輕易遇到out of service的警告。在集羣中,一樣的服務能夠由多個服務實體提供。若是一個服務實體失敗了,另外一個服務實體會接管失敗的服務實體。集羣提供的從一個出錯的服務實體恢復到另外一個服務實體的功能加強了應用的可用性
二、集羣的兩大能力:redis
負載均衡----負載均衡能把任務比較均衡地分佈到集羣環境下的計算和網絡資源。算法
錯誤恢復----因爲某種緣由,執行某個任務的資源出現故障,另外一服務實體中執行同一任務的資源接着完成任務。這種因爲一個實體中的資源不能工做,另外一個實體中的資源透明的繼續完成任務的過程叫錯誤恢復。數據庫
分佈式是將不一樣的業務分佈在不一樣的地方,web應用和數據庫服務分開,將不一樣業務分不到不一樣的集羣。windows
分佈式的特色:ruby
1. 防止單點故障服務器
2. 處理高併發(太多請求,一臺服務器搞不定)
3. 處理大量數據(太多內存數據,一臺服務器處理不過來)
主從同步,讀寫分離,主備切換。
原理:
優勢:
缺點:
自動化的系統監控和故障恢復功能。
優勢:哨兵模式是基於主從模式的,全部主從的優勢,哨兵模式都具備。主從能夠自動切換,系統更健壯,可用性更高。
缺點:比較難擴容,服務佔用空間比較多
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 機制),內部使用二進制協議優化傳輸速度和帶寬。
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
1)選舉過程是集羣中全部master參與,若是半數以上master節點與故障節點通訊超過(cluster-node-timeout),認爲該節點故障,自動觸發故障轉移操做. 故障節點對應的從節點自動升級爲主節點
(2)何時整個集羣不可用(cluster_state:fail)?
若是集羣任意master掛掉,且當前master沒有slave.集羣進入fail狀態,也能夠理解成集羣的slot映射[0-16383]不完成時進入fail狀態。
(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
(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 。
@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. 分佈存儲機制-槽