redis主要架構

導言

redis-cluster是近年來redis架構不斷改進中的相對較好的redis高可用方案。本文涉及到近年來redis多實例架構的演變過程,包括普通主從架構(Master、slave可進行寫讀分離)、哨兵模式下的主從架構、redis-cluster高可用架構(redis官方默認cluster下不進行讀寫分離)的簡介。同時還介紹使用Java的兩大redis客戶端:Jedis與Lettuce用於讀寫redis-cluster的數據的一般方法。再通過官方文檔以及互聯網的相關技術文檔,給出redis-cluster架構下的讀寫能力的優化方案,包括官方的推薦的擴展redis-cluster下的Master數量以及非官方默認的redis-cluster的讀寫分離方案,案例中使用Lettuce的特定方法進行redis-cluster架構下的數據讀寫分離。

近年來redis多實例用架構的演變過程

redis是基於內存的高性能key-value數據庫,若要讓redis的數據更穩定安全,需要引入多實例以及相關的高可用架構。而近年來redis的高可用架構亦不斷改進,先後出現了本地持久化、主從備份、哨兵模式、redis-cluster羣集高可用架構等等方案。

1、redis普通主從模式

通過持久化功能,Redis保證了即使在服務器重啓的情況下也不會損失(或少量損失)數據,因爲持久化會把內存中數據保存到硬盤上,重啓會從硬盤上加載數據。 。但是由於數據是存儲在一臺服務器上的,如果這臺服務器出現硬盤故障等問題,也會導致數據丟失。爲了避免單點故障,通常的做法是將數據庫複製多個副本以部署在不同的服務器上,這樣即使有一臺服務器出現故障,其他服務器依然可以繼續提供服務。爲此, Redis 提供了複製(replication)功能,可以實現當一臺數據庫中的數據更新後,自動將更新的數據同步到其他數據庫上。

在複製的概念中,數據庫分爲兩類,一類是主數據庫(master),另一類是從數據庫(slave)。主數據庫可以進行讀寫操作,當寫操作導致數據變化時會自動將數據同步給從數據庫。而從數據庫一般是隻讀的,並接受主數據庫同步過來的數據。一個主數據庫可以擁有多個從數據庫,而一個從數據庫只能擁有一個主數據庫。

主從模式的配置,一般只需要再作爲slave的redis節點的conf文件上加入“slaveof masterip masterport”, 或者作爲slave的redis節點啓動時使用如下參考命令:

redis-server --port 6380 --slaveof masterIp masterPort   

redis的普通主從模式,能較好地避免單獨故障問題,以及提出了讀寫分離,降低了Master節點的壓力。互聯網上大多數的對redis讀寫分離的教程,都是基於這一模式或架構下進行的。但實際上這一架構並非是目前最好的redis高可用架構。

2、redis哨兵模式高可用架構

當主數據庫遇到異常中斷服務後,開發者可以通過手動的方式選擇一個從數據庫來升格爲主數據庫,以使得系統能夠繼續提供服務。然而整個過程相對麻煩且需要人工介入,難以實現自動化。 爲此,Redis 2.8開始提供了哨兵工具來實現自動化的系統監控和故障恢復功能。 哨兵的作用就是監控redis主、從數據庫是否正常運行,主出現故障自動將從數據庫轉換爲主數據庫。

顧名思義,哨兵的作用就是監控Redis系統的運行狀況。它的功能包括以下兩個。

(1)監控主數據庫和從數據庫是否正常運行。
(2)主數據庫出現故障時自動將從數據庫轉換爲主數據庫。

可以用info replication查看主從情況 例子: 1主2從 1哨兵,可以用命令起也可以用配置文件裏 可以使用雙哨兵,更安全,參考命令如下:

redis-server --port 6379 
redis-server --port 6380 --slaveof 192.168.0.167 6379 
redis-server --port 6381 --slaveof 192.168.0.167 6379
redis-sentinel sentinel.conf 

其中,哨兵配置文件sentinel.conf參考如下:

sentinel monitor mymaster 192.168.0.167 6379 1  

其中mymaster表示要監控的主數據庫的名字。配置哨兵監控一個系統時,只需要配置其監控主數據庫即可,哨兵會自動發現所有複製該主數據庫的從數據庫。
Master與slave的切換過程:
(1)slave leader升級爲master
(2)其他slave修改爲新master的slave
(3)客戶端修改連接
(4)老的master如果重啓成功,變爲新master的slave

3、redis-cluster羣集高可用架構

即使使用哨兵,redis每個實例也是全量存儲,每個redis存儲的內容都是完整的數據,浪費內存且有木桶效應。爲了最大化利用內存,可以採用cluster羣集,就是分佈式存儲。即每臺redis存儲不同的內容。
採用redis-cluster架構正是滿足這種分佈式存儲要求的集羣的一種體現。redis-cluster架構中,被設計成共有16384個hash slot。每個master分得一部分slot,其算法爲:hash_slot = crc16(key) mod 16384 ,這就找到對應slot。採用hash slot的算法,實際上是解決了redis-cluster架構下,有多個master節點的時候,數據如何分佈到這些節點上去。key是可用key,如果有{}則取{}內的作爲可用key,否則整個可以是可用key。羣集至少需要3主3從,且每個實例使用不同的配置文件。

在redis-cluster架構中,redis-master節點一般用於接收讀寫,而redis-slave節點則一般只用於備份,其與對應的master擁有相同的slot集合,若某個redis-master意外失效,則再將其對應的slave進行升級爲臨時redis-master。
在redis的官方文檔中,對redis-cluster架構上,有這樣的說明:在cluster架構下,默認的,一般redis-master用於接收讀寫,而redis-slave則用於備份,當有請求是在向slave發起時,會直接重定向到對應key所在的master來處理。但如果不介意讀取的是redis-cluster中有可能過期的數據並且對寫請求不感興趣時,則亦可通過readonly命令,將slave設置成可讀,然後通過slave獲取相關的key,達到讀寫分離。具體可以參閱redis官方文檔(https://redis.io/commands/readonly)等相關內容:

Enables read queries for a connection to a Redis Cluster slave node.    
Normally slave nodes will redirect clients to the authoritative master for the hash slot involved in a given command, however clients can use slaves in order to scale reads using the READONLY command.    
READONLY tells a Redis Cluster slave node that the client is willing to read possibly stale data and is not interested in running write queries.    
When the connection is in readonly mode, the cluster will send a redirection to the client only if the operation involves keys not served by the slave's master node. This may happen because:  
The client sent a command about hash slots never served by the master of this slave.
The cluster was reconfigured (for example resharded) and the slave is no longer able to serve commands for a given hash slot.

例如,我們假設已經建立了一個三主三從的redis-cluster架構,其中A、B、C節點都是redis-master節點,A1、B1、C1節點都是對應的redis-slave節點。在我們只有master節點A,B,C的情況下,對應redis-cluster如果節點B失敗,則羣集無法繼續,因爲我們沒有辦法再在節點B的所具有的約三分之一的hash slot集合範圍內提供相對應的slot。然而,如果我們爲每個主服務器節點添加一個從服務器節點,以便最終集羣由作爲主服務器節點的A,B,C以及作爲從服務器節點的A1,B1,C1組成,那麼如果節點B發生故障,系統能夠繼續運行。節點B1複製B,並且B失效時,則redis-cluster將促使B的從節點B1作爲新的主服務器節點並且將繼續正確地操作。但請注意,如果節點B和B1在同一時間發生故障,則Redis羣集無法繼續運行。

Redis羣集配置參數:在繼續之前,讓我們介紹一下Redis Cluster在redis.conf文件中引入的配置參數。有些命令的意思是顯而易見的,有些命令在你閱讀下面的解釋後纔會更加清晰。

(1)cluster-enabled :如果想在特定的Redis實例中啓用Redis羣集支持就設置爲yes。 否則,實例通常作爲獨立實例啓動。
(2)cluster-config-file :請注意,儘管有此選項的名稱,但這不是用戶可編輯的配置文件,而是Redis羣集節點每次發生更改時自動保留羣集配置(基本上爲狀態)的文件。
(3)cluster-node-timeout :Redis羣集節點可以不可用的最長時間,而不會將其視爲失敗。 如果主節點超過指定的時間不可達,它將由其從屬設備進行故障切換。
(4)cluster-slave-validity-factor :如果設置爲0,無論主設備和從設備之間的鏈路保持斷開連接的時間長短,從設備都將嘗試故障切換主設備。 如果該值爲正值,則計算最大斷開時間作爲節點超時值乘以此選項提供的係數,如果該節點是從節點,則在主鏈路斷開連接的時間超過指定的超時值時,它不會嘗試啓動故障切換。
(5)cluster-migration-barrier :主設備將保持連接的最小從設備數量,以便另一個從設備遷移到不受任何從設備覆蓋的主設備。有關更多信息,請參閱本教程中有關副本遷移的相應部分。
(6)cluster-require-full-coverage :如果將其設置爲yes,則默認情況下,如果key的空間的某個百分比未被任何節點覆蓋,則集羣停止接受寫入。 如果該選項設置爲no,則即使只處理關於keys子集的請求,羣集仍將提供查詢。

以下是最小的Redis集羣配置文件:

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

注意:
(1)redis-cluster最小配置爲三主三從,當1個主故障,大家會給對應的從投票,把從立爲主,若沒有從數據庫可以恢復則redis羣集就down了。
(2)在這個redis cluster中,如果你要在slave讀取數據,那麼需要帶上readonly指令。redis cluster的核心的理念,主要是用slave做高可用的,每個master掛一兩個slave,主要是做數據的熱備,當master故障時的作爲主備切換,實現高可用的。redis cluster默認是不支持slave節點讀或者寫的,跟我們手動基於replication搭建的主從架構不一樣的。slave node要設置readonly,然後再get,這個時候才能在slave node進行讀取。對於redis -cluster主從架構,若要進行讀寫分離,官方其實是不建議的,但也能做,只是會複雜一些。具體見下面的章節。
(3)redis-cluster的架構下,實際上本身master就是可以任意擴展的,你如果要支撐更大的讀吞吐量,或者寫吞吐量,或者數據量,都可以直接對master進行橫向擴展就可以了。也擴容master,跟之前擴容slave進行讀寫分離,效果是一樣的或者說更好。
(4)可以使用自帶客戶端連接:使用redis-cli -c -p cluster中任意一個端口,進行數據獲取測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章