Redis在互聯(lián)網(wǎng)大數(shù)據(jù)平臺(tái)有著廣泛的應(yīng)用,主要被用來緩存熱點(diǎn)數(shù)據(jù),避免海量請(qǐng)求壓垮數(shù)據(jù)庫,同時(shí)可以提升服務(wù)節(jié)點(diǎn)的響應(yīng)速度和并發(fā)量。隨著數(shù)據(jù)量的增多,由于redis是占用單臺(tái)物理機(jī)或虛機(jī)的內(nèi)存,內(nèi)存資源是有限的,要?jiǎng)討B(tài)地?cái)U(kuò)容縮容,就需要用到redis集群。redis集群的架構(gòu)方案經(jīng)歷了一系列演變和改良的過程,本文介紹了四種主流的redis架構(gòu)方案。
優(yōu)點(diǎn)
不使用第三方中間件,實(shí)現(xiàn)方法和代碼可以自己掌控并且可隨時(shí)調(diào)整。這種分片性能比代理式更好(因?yàn)樯倭朔职l(fā)環(huán)節(jié)),分發(fā)壓力在客戶端,無服務(wù)端壓力增加
缺點(diǎn)
不能平滑地水平擴(kuò)容,擴(kuò)容/縮容時(shí),必須手動(dòng)調(diào)整分片程序,出現(xiàn)故障不能自動(dòng)轉(zhuǎn)移,難以運(yùn)維
優(yōu)點(diǎn)
運(yùn)維成本低。業(yè)務(wù)方不用關(guān)心后端 Redis 實(shí)例,跟操作 Redis 一樣。Proxy 的邏輯和存儲(chǔ)的邏輯是隔離的
缺點(diǎn)
a. 代理層多了一次轉(zhuǎn)發(fā),性能有所損耗
b. 進(jìn)行擴(kuò)容/縮容時(shí)候,部分?jǐn)?shù)據(jù)可能會(huì)失效,需要手動(dòng)進(jìn)行遷移,對(duì)運(yùn)維要求較高,而且難以做到平滑的擴(kuò)縮容
c. 出現(xiàn)故障,不能自動(dòng)轉(zhuǎn)移,運(yùn)維性很差
優(yōu)點(diǎn)
a. 無中心節(jié)點(diǎn)
b. 數(shù)據(jù)按照 Slot 存儲(chǔ)分布在多個(gè) Redis 實(shí)例上
c. 平滑的進(jìn)行擴(kuò)容/縮容節(jié)點(diǎn)
d. 自動(dòng)故障轉(zhuǎn)移(節(jié)點(diǎn)之間通過 Gossip 協(xié)議交換狀態(tài)信息,進(jìn)行投票機(jī)制完成 Slave 到 Master 角
色的提升)
e. 降低運(yùn)維成本,提高了系統(tǒng)的可擴(kuò)展性和高可用性
缺點(diǎn)
a. 嚴(yán)重依賴外部 Redis-Trib
b. 缺乏監(jiān)控管理
c. 需要依賴 Smart Client(連接維護(hù), 緩存路由表, MultiOp 和 Pipeline 支持)
d. Failover 節(jié)點(diǎn)的檢測(cè)過慢,不如“中心節(jié)點(diǎn) ZooKeeper”及時(shí)
e. Gossip 消息的開銷
f. 無法根據(jù)統(tǒng)計(jì)區(qū)分冷熱數(shù)據(jù)
g. Slave“冷備”,不能緩解讀壓力
優(yōu)點(diǎn)
Smart Client:
a. 相比于使用代理,減少了一層網(wǎng)絡(luò)傳輸?shù)南?,效率較高。
b. 不依賴于第三方中間件,實(shí)現(xiàn)方法和代碼自己掌控,可隨時(shí)調(diào)整。
Proxy:
a. 提供一套 HTTP Restful 接口,隔離底層存儲(chǔ)。對(duì)客戶端完全透明,跨語言調(diào)用。
b. 升級(jí)維護(hù)較為容易,維護(hù) Redis Cluster,只需要平滑升級(jí) Proxy。
c. 層次化存儲(chǔ),底層存儲(chǔ)做冷熱異構(gòu)存儲(chǔ)。
d. 權(quán)限控制,Proxy 可以通過秘鑰控制白名單,把一些不合法的請(qǐng)求都過濾掉。并
且也可以控制用戶請(qǐng)求的超大 Value 進(jìn)行控制,和過濾。
e. 安全性,可以屏蔽掉一些危險(xiǎn)命令,比如 Keys、Save、Flush All 等。
f. 容量控制,根據(jù)不同用戶容量申請(qǐng)進(jìn)行容量限制。
g. 資源邏輯隔離,根據(jù)不同用戶的 Key 加上前綴,來進(jìn)行資源隔離。
h. 監(jiān)控埋點(diǎn),對(duì)于不同的接口進(jìn)行埋點(diǎn)監(jiān)控等信息。
缺點(diǎn)
Smart Client:
a. 客戶端的不成熟,影響應(yīng)用的穩(wěn)定性,提高開發(fā)難度。
b. MultiOp 和 Pipeline 支持有限。
c. 連接維護(hù),Smart 客戶端對(duì)連接到集群中每個(gè)結(jié)點(diǎn) Socket 的維護(hù)。
Proxy:
a. 代理層多了一次轉(zhuǎn)發(fā),性能有所損耗。
b.進(jìn)行擴(kuò)容/縮容時(shí)候?qū)\(yùn)維要求較高,而且難以做到平滑的擴(kuò)縮容
redis官方文檔中有如下這段話:
The redis-cli cluster support is very basic so it always uses the fact that Redis Cluster nodes are able to redirect a client to the right node. A serious client is able to do better than that, and cache the map between hash slots and nodes addresses, to directly use the right connection to the right node. The map is refreshed only when something changed in the cluster configuration, for example after a failover or after the system administrator changed the cluster layout by adding or removing nodes.
大意就是目前redis cluster官方客戶端功能簡陋,依賴于redis節(jié)點(diǎn)重定向去到集群中找到數(shù)據(jù)所在的redis實(shí)例。需要有一個(gè)更完善的客戶端,能夠?qū)崿F(xiàn)一致性hash,failover和集群管理功能。因此使用官方的redis cluster客戶端不是一個(gè)明智的選擇,本文提供3種方案供大家參考,如果有不合理的地方,歡迎大家與我共同探討。
方案 1 使用nginx開發(fā)(OpenResty方式)
原因如下
a. 單 Master 多 Work 模式,每個(gè) Work 跟 Redis 一樣都是單進(jìn)程單線程模式,并且都是基
于 Epoll 事件驅(qū)動(dòng)的模式。
b. Nginx 采用了異步非阻塞的方式來處理請(qǐng)求,高效的異步框架。
c. 內(nèi)存占用少,有自己的一套內(nèi)存池管理方式,。將大量小內(nèi)存的申請(qǐng)聚集到一塊,能夠比
Malloc 更快。減少內(nèi)存碎片,防止內(nèi)存泄漏。減少內(nèi)存管理復(fù)雜度。
d. 為了提高 Nginx 的訪問速度,Nginx 使用了自己的一套連接池。
e. 最重要的是支持自定義模塊開發(fā)。
f. 業(yè)界內(nèi),對(duì)于 Nginx,Redis 的口碑可稱得上兩大神器。性能也就不用說了。
方案 2 codis (豌豆莢采用的基于代理的redis集群方案)
參考codis官方文檔https://github.com/CodisLabs/codis
Codis是一整套緩存解決方案,包含高可用、數(shù)據(jù)分片、監(jiān)控、動(dòng)態(tài)擴(kuò)態(tài) etc.。
走的是 Apps->代理->redis cluster,一定規(guī)模后基本都采用這種方式。
方案3 自己獨(dú)立開發(fā)redis智能客戶端
主要實(shí)現(xiàn)redis slots管理,failover,一致性hash功能。
以上就是筆者在實(shí)際工作中總結(jié)和研究的結(jié)果,能力所限,如果您有其它建議和好的思路,歡迎給我留言探討。本頭條號(hào)每天都會(huì)更新互聯(lián)網(wǎng)相關(guān)的技術(shù)分享,歡迎大家訂閱。
聯(lián)系客服