1. 程式人生 > >【修真院java小課堂】REDIS快取叢集介紹

【修真院java小課堂】REDIS快取叢集介紹

大家好,我是IT修真院西安分院第三期學員,一枚正直純潔善良的JAVA程式設計師。 今天給大家分享一下,修真院官網JAVA任務六,深度思考中的知識點——REDIS快取叢集介紹

一、背景介紹

Redis:

Redis 是一個開源(BSD許可)的,記憶體中的資料結構儲存系統,通俗的來講就是基於記憶體的高效能K/V資料庫。 Redis 作為一個key—value儲存系統。支援儲存的value型別相對更多,包括string(字串)、list(連結串列)、set(集合)、zset(sorted set --有序集合)和hash(雜湊雜湊)。

Redis 主從、哨兵的產生背景

主從模式

即使redis提供資料持久化,但由於資料是儲存在一臺伺服器上的,如果這臺伺服器出現硬碟故障等問題,也會導致資料丟失。為了避免單點故障,通常的做法是將資料庫複製多個副本以部署在不同的伺服器上,這樣即使有一臺伺服器出現故障,其他伺服器依然可以繼續提供服務。為此, Redis 提供了複製(replication)功能,可以實現當一臺資料庫中的資料更新後,自動將更新的資料同步到其他資料庫上。

哨兵模式

當主資料庫遇到異常中斷服務後,開發者可以通過手動的方式選擇一個從資料庫來升格為主資料庫,以使得系統能夠繼續提供服務。然而整個過程相對麻煩且需要人工介入,難以實現自動化。 為此,Redis 2.8中提供了哨兵工具來實現自動化的系統監控和故障恢復功能。

叢集(CLUSTER)

叢集是一組相互獨立的、通過高速網路互相聯通的節點,構成了一個組,並以單一系統的模式加以管理。一個客戶與叢集相互作用時,叢集就是一個獨立的伺服器。 叢集技術是一種通用的技術,其目的是為了解決單機運算能力的不足、IO能力的不足、提高服務的可靠性、獲得規模可擴充套件能力,降低整體方案的運維成本(執行、升級、維護成本)。能在大流量訪問下提供穩定的業務,叢集化是儲存的必然形態。 1. 提高效能 2. 降低成本 3. 提高可擴充套件性 4. 增強可靠性

二、知識剖析

redis叢集架構方案發展:

(1)客戶端分片---Java(Jedis客戶端) (2)Twemproxy(基於代理的分片)多加了一個代理層 (3)Codis (4)Redis Cluster(路由查詢--官方實現) (5)Proxy + Redis Cluster

(1)客戶端分片---Java(Jedis客戶端)

Jedis的客戶端分片採用一致性hash演算法,實現資料的分配儲存。但當某一個分片服務掛了之後,客戶端需要修改服務的指向才能動態的切換到當前分片的從服務去。 這是一種靜態的分片方案,需要增加或者減少Redis例項的數量,需要手工調整分片的程式。 • 可運維性差,叢集的資料出了任何問題都需要運維人員和開發人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本。 • 在不同的客戶端程式中,維護相同的分片邏輯成本巨大。

(2)Twemproxy(基於代理的分片)多加了一個代理層

Twemproxy是一個Twitter開源的一個Redis/Memcache代理伺服器, 其基本原理是:Redis客戶端把請求傳送到Twemproxy,Twemproxy根據路由規則傳送到正確的Redis例項,最後Twemproxy把結果彙集返回給客戶端。 Twemproxy通過引入一個代理層,將多個Redis例項進行統一管理,使Redis客戶端只需要在Twemproxy上進行操作,而不需要關心後面有多少個Redis例項,從而實現了Redis叢集。 Twemproxy是早期Redis原生的Cluster沒有成熟時的替代方案,而後Redis官方推薦的高效能叢集方案還是基於其原生的Redis Cluster功能。 最大的問題是Twemproxy無法平滑地增加Redis例項。

(3)Codis

豌豆莢自主研發了Codis, 一個支援平滑增加Redis例項的Redis代理軟體.

(4)Redis Cluster(路由查詢--官方實現)

Redis Cluster從Redis 3.0開始引入,3.2版本趨於成熟。 Redis把所有的Key分成了16384個slot,每個Redis例項負責其中一部分slot。叢集中的所有資訊(節點、埠、slot等),都通過節點之間定期的資料交換而更新。 Redis客戶端在任意一個Redis例項發出請求,如果所需資料不在該例項中,通過重定向命令引導客戶端訪問所需的例項。

(5)Proxy + Redis Cluster

redis叢集的優點

1.快取永不宕機:啟動叢集,永遠讓叢集的一部分起作用。主節點失效了子節點能迅速改變角色成為主節點,整個叢集的部分節點失敗或者不可達的情況下能夠繼續處理命令; 2.迅速恢復資料:持久化資料,能在宕機後迅速解決資料丟失的問題; 3.Redis可以使用所有機器的記憶體,變相擴充套件效能; 4.使Redis的計算能力通過簡單地增加伺服器得到成倍提升,Redis的網路頻寬也會隨著計算機和網絡卡的增加而成倍增長; 5.Redis叢集沒有中心節點,不會因為某個節點成為整個叢集的效能瓶頸。 6.非同步處理資料,實現快速讀寫。

三、常見問題

REDIS叢集實現方式(主從模式)

四、解決方案

REDIS叢集實現方式(主從模式)

流程:

1.建立不同的redis節點,在需要的地方執行redis例項,每個redis例項有單獨的ip或埠,並且配置啟用叢集管理; 2.建立redis-trib的執行環境:安裝ruby,redis.gem 3.通過使用Redis叢集命令工具redis-trib建立叢集; ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 --replicas 1 表示 自動為每一個master節點分配一個slave節點,上面有6個節點,程式會按照一定規則生成3個master(主)3個slave(從)

Redis 叢集的資料分片

Redis 叢集沒有使用一致性hash,而是引入了雜湊槽的概念。 Redis 叢集內建了16384個雜湊槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽。叢集的每個節點負責一部分hash槽,舉個例子,比如當前叢集有3個節點,那麼: 節點 A 包含 0 到 5500號雜湊槽. 節點 B 包含5501 到 11000 號雜湊槽. 節點 C 包含11001 到 16384號雜湊槽. 這種結構很容易新增或者刪除節點.  比如如果我想新添加個節點D,我需要從節點 A, B, C中得部分槽到D上. 如果我想移除節點A,需要將A中的槽移到B和C節點上,然後將沒有任何槽的A節點從叢集中移除即可.  由於從一個節點將雜湊槽移動到另一個節點並不會停止服務,所以無論新增刪除或者改變某個節點的雜湊槽的數量都不會造成叢集不可用的狀態.

redis配置檔案

redis.conf 叢集的配置
#繫結ip(這裡是本地配置,其他伺服器配置對應的ip)
bind 127.0.0.1 
#埠
port 6379
#後臺守護啟動
daemonize yes
#開啟aof模式
appendonly yes
#開啟叢集管理
cluster-enabled yes
#節點響應超時時間 如果超過這個響應時間就會認定節點不可用
cluster-node-timeout 5000

五、編碼實戰

1、啟動: redis-server  7001.conf
連線redis:redis-cli -h 127.0.0.1 -c -p 7005
-h <主機ip>,預設是127.0.0.1
-p <埠>,預設是6379
-a <密碼>,如果redis加鎖,需要傳遞密碼
2、安裝ruby環境: apt-get install ruby ----redis下面這個叢集工具使用ruby語言編寫的
3、redis官方提供的叢集工具: gem install redis
安裝目錄/usr/share/doc/redis-tools/examples/
4、叢集命令:./redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006

六、擴充套件思考

MEMCACHE和REDIS叢集的對比

Memcached本身並不支援分散式,因此只能在客戶端通過像一致性雜湊這樣的分散式演算法來實現Memcached的分散式儲存。 當客戶端向Memcached叢集傳送資料之前,首先會通過內建的分散式演算法計算出該條資料的目標節點,然後資料會直接傳送到該節點上儲存。但客戶端查詢資料時,同樣要計算出查詢資料所在的節點,然後直接向該節點發送查詢請求以獲取資料。

Redis官方叢集方案 Redis Cluster Redis Cluster是一種伺服器Sharding技術,3.0版本開始正式提供。對客戶端來說,整個cluster被看做是一個整體,客戶端可以連線任意一個node進行操作,就像操作單一Redis例項一樣,當客戶端操作的key沒有分配到該node上時,就像操作單一Redis例項一樣,當客戶端操作的key沒有分配到該node上時,Redis會返回轉向指令,指向正確的node

七、參考文獻

https://blog.csdn.net/onupway/article/details/78387368

https://www.cnblogs.com/robin201711/p/8516844.html

8.更多討論

1、redis叢集的增加刪除節點


(1)增加主節點:./redis-trib.rb add-node 127.0.0.1:9004 127.0.0.1:9001
第一個引數是新例項,第二個引數是叢集中已有的節點。
(2)檢視節點: cluster nodes
(3)增加從節點: ./redis-trib.rb add-node --slave 127.0.0.1:9005 127.0.0.1:9001
(4)刪除節點: ./redis-trib.rb del-node 127.0.0.1:9001 'cbb01bdfdc265b190496956354d84aaae6e7d54d'
第一個引數是叢集中的任何一個主節點地址,而第二個引數是要刪除節點的 ID; 要刪除的節點必須是空的,也就是不能快取任何資料,否則會刪除不成功。
(5)重新分片: ./redis-trib.rb reshard 127.0.0.1:9003

2、Redis叢集方案什麼情況下會導致整個叢集不可用?

(1)如果叢集任意master掛掉,且當前master沒有slave.叢集進入fail狀態,也可以理解成叢集的slot對映[0-16383]不完成時進入fail狀態.

(2)如果叢集超過半數以上master掛掉,無論是否有slave叢集進入fail狀態.

3、Redis叢集之間是如何複製的?

採用非同步複製。從 Redis 2.8 開始,從伺服器會週期性地報告從複製流中處理的資料量。 

感謝觀看,如有出錯,懇請指正