由於Redis出眾的性能,其在眾多的移動互聯網企業中得到廣泛的應用。Redis在3.0版本前只支持單實例模式,雖然現在的服務器內存可以到100GB、200GB的規模,但是單實例模式限制了Redis沒法滿足業務的需求(例如新浪微博就曾經用Redis存儲了超過1TB的數據)。Redis的開發者Antirez早在博客上就提出在Redis 3.0版本中加入集群的功能,但3.0版本等到2015年才發布正式版。各大企業在3.0版本還沒發布前為了解決Redis的存儲瓶頸,紛紛推出了各自的Redis集群方案。這些方案的核心思想是把數據分片(sharding)存儲在多個Redis實例中,每一片就是一個Redis實例。
下面介紹Redis的集群方案。
1、客戶端分片
客戶端分片是把分片的邏輯放在Redis客戶端實現,通過Redis客戶端預先定義好的路由規則,把對Key的訪問轉發到不同的Redis實例中,最后把返回結果匯集。這種方案的模式如下圖所示。
客戶端分片的好處是所有的邏輯都是可控的,不依賴於第三方分布式中間件。開發人員清楚怎么實現分片、路由的規則,不用擔心踩坑。
客戶端分片方案有下面這些缺點:
●這是一種靜態的分片方案,需要增加或者減少Redis實例的數量,需要手工調整分片的程序。
●可運維性差,集群的數據出了任何問題都需要運維人員和開發人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本。
●在不同的客戶端程序中,維護相同的分片邏輯成本巨大。例如,系統中有兩套業務系統共用一套Redis集群,一套業務系統用Java實現,另一套業務系統用PHP實現。為了保證分片邏輯的一致性,在Java客戶端中實現的分片邏輯也需要在PHP客戶端實現一次。相同的邏輯在不同的系統中分別實現,這種設計本來就非常糟糕,而且需要耗費巨大的開發成本保證兩套業務系統分片邏輯的一致性。
2、Twemproxy
Twemproxy是由Twitter開源的Redis代理,其基本原理是:Redis客戶端把請求發送到Twemproxy,Twemproxy根據路由規則發送到正確的Redis實例,最后Twemproxy把結果匯集返回給客戶端。
Twemproxy通過引入一個代理層,將多個Redis實例進行統一管理,使Redis客戶端只需要在Twemproxy上進行操作,而不需要關心后面有多少個Redis實例,從而實現了Redis集群。
Twemproxy集群架構如下圖所示:
Twemproxy的優點如下:
●客戶端像連接Redis實例一樣連接Twemproxy,不需要改任何的代碼邏輯。
●支持無效Redis實例的自動刪除。
●Twemproxy與Redis實例保持連接,減少了客戶端與Redis實例的連接數。
Twemproxy的缺點如下:
●由於Redis客戶端的每個請求都經過Twemproxy代理才能到達Redis服務器,這個過程中會產生性能損失。
●沒有友好的監控管理后台界面,不利於運維監控。
●最大的問題是Twemproxy無法平滑地增加Redis實例。對於運維人員來說,當因為業務需要增加Redis實例時工作量非常大。
Twemproxy作為最被廣泛使用、最久經考驗、穩定性最高的Redis代理,在業界被廣泛使用。
3、Redis 3.0集群
Redis 3.0集群采用了P2P的模式,完全去中心化。Redis把所有的Key分成了16384個slot,每個Redis實例負責其中一部分slot。集群中的所有信息(節點、端口、slot等),都通過節點之間定期的數據交換而更新。
Redis客戶端在任意一個Redis實例發出請求,如果所需數據不在該實例中,通過重定向命令引導客戶端訪問所需的實例。
Redis 3.0集群的工作流程如下圖所示:
如圖所示Redis集群內的機器定期交換數據,工作流程如下:
(1) Redis客戶端在Redis2實例上訪問某個數據。
(2) 在Redis2內發現這個數據是在Redis3這個實例中,給Redis客戶端發送一個重定向的命令。
(3) Redis客戶端收到重定向命令后,訪問Redis3實例獲取所需的數據。
Redis 3.0的集群方案有以下兩個問題:
●一個Redis實例具備了“數據存儲”和“路由重定向”,完全去中心化的設計。這帶來的好處是部署非常簡單,直接部署Redis就行,不像Codis有那么多的組件和依賴。但帶來的問題是很難對業務進行無痛的升級,如果哪天Redis集群出了什么嚴重的Bug,就只能回滾整個Redis集群。
●對協議進行了較大的修改,對應的Redis客戶端也需要升級。升級Redis客戶端后誰能確保沒有Bug?而且對於線上已經大規模運行的業務,升級代碼中的Redis客戶端也是一個很麻煩的事情。
綜合上面所述的兩個問題,Redis 3.0集群在業界並沒有被大規模使用。
4、雲服務器上的集群服務
國內的雲服務器提供商阿里雲、UCloud等均推出了基於Redis的雲存儲服務。
這個服務的特性如下。
(1)動態擴容
用戶可以通過控制面板升級所需的Redis存儲空間,擴容的過程中服務部不需要中斷或停止,整個擴容過程對用戶透明、無感知,這點是非常實用的,在前面介紹的方案中,解決Redis平滑擴容是個很煩瑣的任務,現在按幾下鼠標就能搞定,大大減少了運維的負擔。
(2)數據多備
數據保存在一主一備兩台機器中,其中一台機器宕機了,數據還在另外一台機器上有備份。
(3)自動容災
主機宕機后系統能自動檢測並切換到備機上,實現服務的高可用。
(4)實惠
很多情況下為了使Redis的性能更高,需要購買一台專門的服務器用於Redis的存儲服務,但這樣子CPU、內存等資源就浪費了,購買Redis雲存儲服務就很好地解決了這個問題。
有了Redis雲存儲服務,能使App后台開發人員從煩瑣運維中解放出來。App后台要搭建一個高可用、高性能的Redis服務,需要投入相當的運維成本和精力。如果使用雲存儲服務,就沒必要投入這些成本和精力,可以讓App后台開發人員更專注於業務。