背景簡(jiǎn)介
BDRP(baidu distributed redis platform)是包含twemproxy嘲玫,redis,redis-sentinel 等多個(gè)模塊開發(fā)的分布式 redis 平臺(tái)并扇。bdrp 已經(jīng)在 github 上進(jìn)行了開源去团,bdrp 的 github 項(xiàng)目點(diǎn)這里
系統(tǒng)架構(gòu)
目前 redis 集群架構(gòu)主要有以下幾個(gè)組件: twemproxy:redis 的代理系統(tǒng),可以選擇多種數(shù)據(jù)分片算法 redis:集群的 redis 存儲(chǔ)節(jié)點(diǎn) sentinel:redis 官方的集群高可用組件穷蛹,可以監(jiān)控 redis 主節(jié)點(diǎn)故障土陪,并進(jìn)行主備切換
對(duì)比開源版本 twemproxy 解決方案,我們?yōu)榧禾砑恿嗣總€(gè) redis 數(shù)據(jù)分片的主從架構(gòu)肴熏,并且添加了 sentinel 模塊鬼雀,基于這些架構(gòu)的拓展,我們實(shí)現(xiàn)了集群的高可用蛙吏,數(shù)據(jù)高可靠的解決方案源哩,集群數(shù)據(jù)讀寫請(qǐng)求分離方案。另外鸦做,針對(duì)線上的復(fù)雜應(yīng)用環(huán)境励烦,我們還未 twemproxy 增加了權(quán)限管理,流量控制(開發(fā)中)兩個(gè)功能泼诱。 下面我們就分別簡(jiǎn)單介紹下這四個(gè)新添加的功能坛掠。
功能介紹
1,高可用切換
由于 twemproxy 開源版本對(duì)于集群的高可用方案只提供了自動(dòng)彈出數(shù)據(jù)分片功能治筒,因此如果應(yīng)用方如果需要高可用集群的話屉栓,需要打開自動(dòng)彈出功能。但是耸袜,即便是對(duì)于一致性哈希分片算法友多,彈出一個(gè)分片也是會(huì)造成一個(gè)分片的數(shù)據(jù)丟失的。對(duì)于數(shù)據(jù)可靠性的要求比較高的服務(wù)來說堤框,如果丟失整個(gè)分片的數(shù)據(jù)是無法接受的域滥。 我們基于 redis 官方的 sentinel 模塊纵柿,實(shí)現(xiàn)了 redis 集群的節(jié)點(diǎn)高可用,數(shù)據(jù)高可靠方案骗绕。如上面的架構(gòu)圖所示藐窄,redis 集群的所有 redis 分片资昧,都配置了對(duì)應(yīng)的從庫酬土,通過 redis 主從傳輸進(jìn)行元數(shù)據(jù)復(fù)制。同時(shí)格带,每個(gè) redis 分片都會(huì)用 sentinel 進(jìn)行監(jiān)控撤缴,當(dāng)分片的主 redis 節(jié)點(diǎn)故障時(shí),sentinel 會(huì)將該分片的從節(jié)點(diǎn)切換成主節(jié)點(diǎn)叽唱。 twemproxy 和 sentinel 之前維護(hù)一個(gè)長連接屈呕,并訂閱 sentinel 的主從切換事件頻道。一旦 sentinel 上發(fā)生了 redis 的主從切換棺亭,twemproxy 馬上就能感知到虎眨,然后調(diào)整自己的分片拓?fù)鋱D,將后續(xù)的請(qǐng)求發(fā)送到新的主庫上镶摘。 twemproxy 在每次和 sentinel 建立連接后嗽桩,都會(huì)從 sentinel 拉取全量的數(shù)據(jù)分片地址信息,避免啟動(dòng)時(shí)的配置錯(cuò)誤凄敢,或者運(yùn)行中連接重建碌冶,丟失主從切換信息。
2涝缝,讀寫分離
![bdrp2](http://op.baidu.com/wp-content/uploads/2014/07/bdrp2.jpg)
bdrp2
對(duì)于數(shù)據(jù)量不是很大扑庞,但是請(qǐng)求量很大的服務(wù)來說,數(shù)據(jù)分片拆分并不是很好的解決方案拒逮,產(chǎn)品線通常會(huì)給數(shù)據(jù)分片配置多個(gè)只讀從庫罐氨,分擔(dān)讀請(qǐng)求。為了支持這種需求滩援,我們給 twemproxy 增加了讀寫分離功能岂昭。 如上架構(gòu)圖,展示了一個(gè) server pool 下面掛接兩個(gè)數(shù)據(jù)分片狠怨,每個(gè)數(shù)據(jù)分片掛接兩個(gè)只讀從庫的情景下的架構(gòu)圖约啊。通過 redis 主從復(fù)制,給每個(gè)數(shù)據(jù)分片配置多個(gè)只讀從庫佣赖。Proxy 從配置中加載到分片從庫信息后恰矩,在每次轉(zhuǎn)發(fā)請(qǐng)求時(shí),判斷請(qǐng)求的類型憎蛤,然后根據(jù)請(qǐng)求是否修改 redis 元數(shù)據(jù)外傅,來決定轉(zhuǎn)發(fā)到主庫或者從庫纪吮。對(duì)于配置了多個(gè)從庫的情況,我們會(huì)對(duì)這幾個(gè)從庫進(jìn)行 round-robin 輪詢 同樣的萎胰,當(dāng)一個(gè)從庫發(fā)生故障碾盟,proxy 會(huì)自動(dòng)剔除這個(gè)從庫,當(dāng)全部從庫都故障技竟,proxy 會(huì)將只讀請(qǐng)求發(fā)送到主庫上冰肴。剔除故障從庫之后,proxy 會(huì)定期對(duì)故障從庫進(jìn)行健康檢查榔组,如果從庫恢復(fù)熙尉,proxy 會(huì)自動(dòng)將該從庫加回讀請(qǐng)求輪詢列表當(dāng)中。
3搓扯,權(quán)限驗(yàn)證白名單
對(duì)于線上服務(wù)來說检痰,完善的權(quán)限管理是必不可少的。但是 twemproxy 并沒有提供權(quán)限驗(yàn)證相關(guān)的功能锨推。我們添加了基于 IP 白名單的權(quán)限驗(yàn)證功能铅歼。用戶可以配置某些 IP 可以擁有的權(quán)限(讀 / 寫),在 client 連接上來之后换可,proxy 會(huì)去判斷 client ip 是否在白名單之內(nèi)椎椰,如果在的話,會(huì)將對(duì)應(yīng)權(quán)限賦予該 client 連接锦担,否則將會(huì)強(qiáng)行斷掉連接俭识。當(dāng)連接上的 client 發(fā)送命令過來后,會(huì)驗(yàn)證該 client 是否有該命令對(duì)應(yīng)的權(quán)限(讀 / 寫)洞渔,如果沒有的話套媚,該連接將會(huì)被強(qiáng)行關(guān)閉。
4磁椒,流量控制
twemproxy 本身支持開啟多個(gè) server_pool堤瘤,后端掛接不同的 redis 數(shù)據(jù)分片。這樣浆熔,單個(gè) proxy 實(shí)例可以服務(wù)多個(gè)應(yīng)用方本辐。但是對(duì)于這種多個(gè)服務(wù)混用 proxy 的情況,twemproxy 并沒有對(duì)各個(gè)應(yīng)用方做流量控制医增。這樣造成的一個(gè)問題是慎皱,可能一個(gè)應(yīng)用方的請(qǐng)求異常突增,占用了過多的 proxy 資源叶骨,從而影響了其他的應(yīng)用方的正常服務(wù)請(qǐng)求茫多。 針對(duì)這種情況,我們決定開發(fā)一個(gè)基于 proxy 的 server pool 的流控忽刽。簡(jiǎn)單來說就是給每個(gè) server pool 一定的配額天揖,當(dāng)某個(gè)應(yīng)用方請(qǐng)求異常突增將其配額耗盡后夺欲,我們將會(huì)拒絕這個(gè)應(yīng)用方的請(qǐng)求,從而避免該異常應(yīng)用方請(qǐng)求影響到其他應(yīng)用方今膊。 流控功能還在設(shè)計(jì)開發(fā)當(dāng)中些阅,因而本次開源版本中并不包括這個(gè)功能。
5斑唬,其他說明
github 上面的開源方案使用的 redis 版本是 2.6.16市埋,這個(gè)版本是沒有主從數(shù)據(jù)增量重傳(partial synchronization)功能的,從庫宕機(jī)需要進(jìn)行全量重傳赖钞,造成性能抖動(dòng)腰素。因此我們 merge 了 2.8 的增量重傳代碼以規(guī)避此問題聘裁。
應(yīng)用范圍
bdrp 在百度檢索系統(tǒng)雪营,百度商業(yè)產(chǎn)品體系,LBS 產(chǎn)品體系等在線業(yè)務(wù)廣泛應(yīng)用衡便。