Redis集羣方案
Redis數據量日益增大,而且使用的公司越來越多,不僅用於做緩存,同時趨向於存儲這塊,這樣必促使集羣的發展,各個公司也在收集適合自己的集羣方案,目前行業用的比較多的是下面幾種集羣架構,大部分都是採用分片技術,解決單實例內存增大帶來的一系列問題。
本篇文章簡單介紹五種方案:
-
官方cluster方案
-
twemproxy代理方案
-
哨兵模式
-
codis
-
客戶端分片
官方cluser方案
從redis 3.0版本開始支持redis-cluster集羣,redis-cluster採用無中心結構,每個節點保存數據和整個集羣狀態,每個節點都和其他節點連接。redis-cluster是一種服務端分片技術。
redis-cluster架構圖
redis-cluster特點:
-
每個節點都和n-1個節點通信,這被稱爲集羣總線(cluster bus)。它們使用特殊的端口號,即對外服務端口號加10000。所以要維護好這個集羣的每個節點信息,不然會導致整個集羣不可用,其內部採用特殊的二進制協議優化傳輸速度和帶寬。
-
redis-cluster把所有的物理節點映射到[0,16383]slot(槽)上,cluster負責維護node--slot--value。
-
集羣預分好16384個桶,當需要在redis集羣中插入數據時,根據CRC16(KEY) mod 16384的值,決定將一個key放到哪個桶中。
-
客戶端與redis節點直連,不需要連接集羣所有的節點,連接集羣中任何一個可用節點即可。
-
redis-trib.rb腳本(rub語言)爲集羣的管理工具,比如自動添加節點,規劃槽位,遷移數據等一系列操作。
-
節點的fail是通過集羣中超過半數的節點檢測失效時才生效。
整個cluster被看做是一個整體,客戶端可連接任意一個節點進行操作,當客戶端操作的key沒有分配在該節點上時,redis會返回轉向指令,指向正確的節點。
爲了增加集羣的可訪問性,官方推薦的方案是將node配置成主從結構,即一個master主節點,掛n個slave從節點。如果主節點失效,redis cluster會根據選舉算法從slave節點中選擇一個上升爲master節點,整個集羣繼續對外提供服務。
twemproxy代理方案
twemproxy代理架構圖:
Redis代理中間件twemproxy是一種利用中間件做分片的技術。twemproxy處於客戶端和服務器的中間,將客戶端發來的請求,進行一定的處理後(sharding),再轉發給後端真正的redis服務器。也就是說,客戶端不直接訪問redis服務器,而是通過twemproxy代理中間件間接訪問。降低了客戶端直連後端服務器的連接數量,並且支持服務器集羣水平擴展。
twemproxy中間件的內部處理是無狀態的,它本身可以很輕鬆地集羣,這樣可以避免單點壓力或故障。
twemproxy又稱nutcracker,起源於推特系統中redis、memcached集羣的輕量級代理。
Github源碼地址(https://github.com/twitter/twemproxy)
從上面架構圖看到twemproxy是一個單點,很容易對其造成很大的壓力,所以通常會結合keepalived來實現twemproy的高可用。這時,通常只有一臺twemproxy在工作,另外一臺處於備機,當一臺掛掉以後,vip自動漂移,備機接替工作。關於keepalived的用法可自行網上查閱資料。
哨兵模式
Sentinel哨兵
Sentinel(哨兵)是Redis的高可用性解決方案:由一個或多個Sentinel實例組成的Sentinel系統可以監視任意多個主服務器以及這些主服務器下的所有從服務器,並在被監視的主服務器進入下線狀態時,自動將下線主服務器屬下的某個從服務器升級爲新的主服務器。
例如:
在Server1掉線後:
升級Server2爲新的主服務器:
Sentinel的工作方式
-
每個Sentinel以每秒鐘一次的頻率向它所知的Master、Slave以及其他Sentinel實例發送一個PING命令。
-
如果一個實例距離最後一次有效回覆PING命令的時間超過down-after-milliseconds選項所指定的值,則這個實例會被Sentinel標記爲主觀下線。
-
如果一個Master被標記爲主觀下線,則正在監視這個Master的所有Sentinel要以每秒一次的頻率確認Master的確進入了主觀下線狀態。
-
當有足夠數量的Sentinel(大於等於配置文件指定的值)在指定的時間範圍內確認Master的確進入了主觀下線狀態,則Master會被標記爲客觀下線。
-
在一般情況下,每個Sentinel會以每10秒一次的頻率向它所知的所有Master、Slave發送INFO命令。
-
當Master被Sentinel標記爲客觀下線時,Sentinel向下線的Master的所有Slave發送INFO命令的頻率會從10秒一次改爲每秒一次。
-
若沒有足夠數量的Sentinel同意Master已經下線,Master的客觀下線狀態就會被移除。若Master重新向Sentinel的PING命令返回有效值,Master的主觀下線狀態就會被移除。
codis
codis是一個分佈式的Redis解決方案,由豌豆莢開源,對於上層的應用來說,連接codis proxy和連接原生的redis server沒什麼明顯的區別,上層應用可以像使用單機的redis一樣使用,codis底層會處理請求的轉發,不停機的數據遷移等工作,所有後邊的事情,對於前面的客戶端來說是透明的,可以簡單的認爲後邊連接的是一個內存無限大的redis服務。
客戶端分片
分區的邏輯在客戶端實現,由客戶端自己選擇請求到哪個節點。方案可參考一致性哈希,這種方案通常適用於用戶對客戶端的行爲有完全控制能力的場景。