Mr-Redis
是華為基于mesos開發(fā)的一個(gè)redis framework , 方便管理 redis 實(shí)例和集群 (github url: https://github.com/mesos/mr-redis)律罢。Mr-Redis 可以創(chuàng)建單個(gè)實(shí)例膀值,也可以創(chuàng)建主從實(shí)例,并實(shí)現(xiàn)了高可用, 這比使用 redis-sentinel 來實(shí)現(xiàn) redis 高可用架構(gòu)上簡(jiǎn)單很多误辑。下面是我從測(cè)試Mr-Redis
到上線過程中遇到的問題沧踏,希望對(duì)正在打算使用和調(diào)研Mr-Redis
的同學(xué)有所幫助...
Mr-Redis特點(diǎn)
充分使用數(shù)據(jù)中心的資源
創(chuàng)建一個(gè)redis實(shí)例的時(shí)間為秒級(jí)
-
failover 的時(shí)間為秒級(jí)
(在沙箱測(cè)試failover時(shí)把 redis 容器stop, 幾秒種內(nèi)會(huì)啟動(dòng)一個(gè)新的redis容器,ip和端口可能會(huì)發(fā)生變化巾钉,沒有做主從的 redis 數(shù)據(jù)會(huì)丟失翘狱,做了主從的數(shù)據(jù)不會(huì)丟失)
Mr-Redis 解決了客服系統(tǒng)中哪些問題
每個(gè)微服務(wù)都擁有自己的
redis
, 所以隨著業(yè)務(wù)增長(zhǎng),微服務(wù)的拆分砰苍,redis
實(shí)例會(huì)不斷的增長(zhǎng)潦匈,通過Mr-Redis
統(tǒng)一管理可以簡(jiǎn)化運(yùn)維工作量Mr-Redis
提供了 redis 的高可用,解決線上 redis 單點(diǎn)的問題
部署架構(gòu)
使用 Mr-Redis 遇到的問題
-
通過
Mr-Redis
部署的 redis 性能會(huì)損失多少和作者 Dhilip Kumar 聊過,他說 redis 性能會(huì)損失 30% 左右赚导,當(dāng)時(shí)不確定性能是在哪里損失掉的茬缩,經(jīng)過沙箱測(cè)試發(fā)現(xiàn)性能是損失在proxy轉(zhuǎn)發(fā)上面了,我的壓測(cè)結(jié)果顯示go-proxy損失了30-40%的性能吼旧,以后會(huì)逐步分析這個(gè)proxy是不是有改進(jìn)的空間凰锡。`如果服務(wù)對(duì) redis qps 要求特別高,建議考慮其他集群方案`**
-
redis 實(shí)例 failover 后, 客戶端如何發(fā)現(xiàn)新的redis 地址
為了解決這個(gè)問題寡夹,我們做了如下改進(jìn):
- redis 信息儲(chǔ)存在 zk 里处面, 去掉 config.json 這個(gè)依賴, 初始化還有同步操作都從zk中讀取
- 每個(gè) mesos slave 機(jī)器上的 proxy 所代理的 redis 在本地的轉(zhuǎn)發(fā)端口是一致的 (利用zk的一致性實(shí)現(xiàn)的)
1. 最開始考慮的做法是想根據(jù)redis name hash成一個(gè)固定并且唯一的 在6100 - 6300區(qū)間的一個(gè)端口號(hào)厂置, 不過這種方式可能沖突幾率比較大 2. 本地proxy每次啟動(dòng)的時(shí)候都去zk讀取本地監(jiān)聽的端口號(hào) (eg: 6166) 3. 新建redis,隨機(jī)選取6100 ~ 6300 之間的一個(gè)端口號(hào) 并且在zk里不存在菩掏,然后存在zk 4. 采用輪詢方式,proxy 會(huì)定時(shí)去獲取 zk 中 redis 相關(guān)信息 之前準(zhǔn)備用zk的事件通知機(jī)制來處理, 不過由于 Mr-Redis 在 zk 中的數(shù)據(jù)結(jié)構(gòu)復(fù)雜昵济, 不能 通過childrenW 簡(jiǎn)單的實(shí)現(xiàn)智绸, 所以只好折衷選擇了輪訓(xùn)的方式來獲取 proxy 代理的 redis 信息
-
scheduler 重啟之后不會(huì)從zk中l(wèi)oad redis信息,dashboard上不會(huì)顯示任何redis實(shí)例访忿,但是redis實(shí)例確實(shí)還在運(yùn)行瞧栗。
這個(gè)問題可以通過一個(gè) tricky 的方式來解決,在 zk 中查詢出所有運(yùn)行中的 redis 實(shí)例名稱(eg. redis_name), 對(duì)每一個(gè)實(shí)例執(zhí)行 curl <scheduler_ip>:5656/v1/STATUS/redis_name, 執(zhí)行完這個(gè)命令海铆, dashboard 上就會(huì)顯示所有運(yùn)行的 redis 實(shí)例
-
在 dashboard 中創(chuàng)建 redis 實(shí)例迹恐,dashboard 上不會(huì)自動(dòng)更新
可以手動(dòng)刷新,如果有時(shí)間可以幫忙解一下這個(gè)bug
-
MrRedisExecutor 運(yùn)行過程中 docker pull 拉取 redis 鏡像的時(shí)候會(huì)連接外網(wǎng),如果沒有外網(wǎng)會(huì)報(bào)錯(cuò)。為了解決這個(gè)問題可以在內(nèi)網(wǎng)環(huán)境里可以為 dockerd 配置代理 也可以在內(nèi)網(wǎng)里搭建自己的 docker registry
https://docs.docker.com/engine/admin/systemd/#httphttps-proxy
錯(cuò)誤信息:
dockerd: time="2017-08-29T12:19:16.361567332+08:00" level=error msg="Not continuing with pull after error: Network timed out while trying to connect to https://index.docker.io/v1/repositories/library/redis/images. You may want to check your internet connection or if you are behind a proxy."
-
mr-redis scheduler 配置文件中不支持寫多zk地址, 導(dǎo)致 zk 會(huì)成為單點(diǎn)
提了一個(gè)pr
https://github.com/mesos/mr-redis/pull/70
需要重新編譯 scheduler 和 MrRedisExecutor.
-
Mr-Redis scheduler 高可用
不能像 marathon 那樣實(shí)現(xiàn) failover (3個(gè)實(shí)例风宁,一個(gè) leader, 另外2個(gè) follower, 當(dāng) leader 掛掉的時(shí)候藤乙,follower會(huì)自動(dòng)選舉出leader), scheduler 的 leader 掛掉后,另外2個(gè) follower 沒有得到通知茁计。解決方法:
通過 marathon 只起一個(gè) scheduler 實(shí)例, constrains 配置為 hostname:UNIQUE, 這樣配置如果 scheduler 所在服務(wù)器宕機(jī), 會(huì)在其他機(jī)器重新啟動(dòng)一個(gè)scheduler, 并重新連接master是偷。經(jīng)過多種 redis 破壞性測(cè)試,redis 都是可以 failover的募逞。
需要改進(jìn)的地方
- 查看本地 redis 代理監(jiān)聽端口列表需要通過api調(diào)用蛋铆,可以考慮加到dashboard上方便查看
- 提供 proxy 轉(zhuǎn)發(fā)性能, 減少 redis qps 損耗
- redis 內(nèi)存彈性擴(kuò)容