Twemproxy來自Twitter的Redis代理
來源:程序員人生 發(fā)布時間:2015-01-16 09:03:34 閱讀次數(shù):4212次
在大量用戶大范圍使用大型Redis節(jié)點的時候,目前從項目本身來看Redis基本上可以說是1個單例的業(yè)務。
關(guān)于這個項目的散布式我有1個很大的想法,在這個想法下,我不需要去對多線程版本的Redis做任何評估:在這個角度上對我來講,1個核就像是1臺計算機,所以在多核上擴大就相當于散布在計算機之間的集群。多實例是1個無同享的架構(gòu)。如果我們找到1個可用的方式來分片,那末所有事情就公道了。 :-)
這也是為何集群會成為Redis在2013年的焦點,并且,終究Redis 2.6的發(fā)布表現(xiàn)出了很好的穩(wěn)定性和成熟度,現(xiàn)在正是時候來關(guān)注Redis Cluster, Redis Sentinel, 和1些其它期待已久的改進。
但是現(xiàn)實狀態(tài)是,Redis Cluster目前依然沒有發(fā)布,正式版還需要幾個月的工作。但是我們的用戶已需要將數(shù)據(jù)分片到不同的實例上來做負載均衡,更重要的是為數(shù)據(jù)取得更大的內(nèi)存存儲。
目前保底的結(jié)局方案是客戶端分片。客戶端分片有很多好處,例如:在客戶端和節(jié)點之間沒有中間層,這就意味著它是1個擴大性很好的設置(主要是線性擴大)。但是要穩(wěn)定的實現(xiàn)(客戶端分片)需要進行1些優(yōu)化,需要1個同步客戶端配置的方式,也需要客戶端支持1致性哈希或其它分區(qū)算法。
有1個重大消息來自Twitter,世界最大的Redis集群之1部署在Twitter用于為用戶提供時間軸數(shù)據(jù)。所以絕不奇怪這篇文章討論的項目來自Twitter Open Source部門。
Twemproxy
---
Twemproxy是1個快速的單線程代理程序,支持Memcached ASCII協(xié)議和更新的Redis協(xié)議:
它全部用C寫成,使用Apache 2.0 License授權(quán)。
項目在Linux上可以工作,而在OSX上沒法編譯,由于它依賴了epoll API.
我的測試環(huán)境為Ubuntu 12.04桌面版。
好吧,閑話少敘。twemproxy到底做了甚么?(注:我將關(guān)注Redis到部份,但是該項目也能夠?qū)emcached做相同到事情)
1) 在客戶端和眾多Redis實例間作為代理。
2) 在配置的Redis實例之間進行自動到數(shù)據(jù)分片。
3) 支持1致性哈希,支持不同到策略和哈希方法。
Twemproxy最了不起的地方就在于它能在節(jié)點失敗的時候卸載它,然后可以在1段時間以后重新嘗試(隨即)連接,又或可以嚴格依照配置文件中寫的鍵與
服務器之間對應關(guān)系進行連接。這意味著Twemproxy能勝任把Redis當作數(shù)據(jù)存儲(不能容忍節(jié)點未命中)的場景,也能夠勝任當作緩存來使用,那些允許(它意味著少許,不是說低質(zhì)量)未命中且高可用的場景。
總結(jié)來講就是:如果你能容忍未命中,那末當有節(jié)點失敗你的數(shù)據(jù)或許會存儲到其他節(jié)點,所以它會是弱1致性的。另外一方面,如果你不能容忍未命中,那末你需要1個具有高可用的實例的方案,例如使用Redis監(jiān)控的失敗自動切換功能。
安裝
---
在深入項目的更多特性之前,有1個好消息,它在Linux上非常容易構(gòu)建。好吧,沒有Redis那末簡單,但是……你僅僅需要簡單依照下面的幾步操作:
apt-get install automake
apt-get install libtool
git clone git://github.com/twitter/twemproxy.git
cd twemproxy
autoreconf -fvi
./configure --enable-debug=log
make
src/nutcracker -h
它的配置也非常簡單,在項目的github頁面上有足夠的文檔可讓你有1個平滑的初體驗。我使用了以下的配置:
redis1:
listen: 0.0.0.0:9999
redis: true
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: true
timeout: 400
server_retry_timeout: 2000
server_failure_limit: 1
servers:
- 127.0.0.1:6379:1
- 127.0.0.1:6380:1
- 127.0.0.1:6381:1
- 127.0.0.1:6382:1
redis2:
listen: 0.0.0.0:10000
redis: true
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: false
timeout: 400
servers:
- 127.0.0.1:6379:1
- 127.0.0.1:6380:1
- 127.0.0.1:6381:1
- 127.0.0.1:6382:1
第1個集群配置為(故障時)節(jié)點自動排除,第2個集群則在所有實例上配置了靜態(tài)映照。
有趣的是,針對同1組
服務器你能同時有多個部署。但是在生產(chǎn)環(huán)境更合適使用多個示例以利用多核的能力。
單點失效?
---
還有另外一件有趣的事情,使用這個部署其實不意味著有單點失效問題,你可以通過運行多套twemproxy,讓你的客戶端連接到第1個可用的實例。
通過使用twemproxy你基本上把分片邏輯和客戶端進行了分離。在這類情況下,1個基本的客戶端就能夠?qū)崿F(xiàn)目的,分片將完全由代理來處理。
這是1個直接而安全的方法,個人觀點。
現(xiàn)在Redis Cluster還不成熟,twemproxy是大多數(shù)希望利用Redis集群的用戶的好方法。也不要太激動,先看看這類方法的限制 ;)
不足
---
我認為Twemproxy沒有支持批量操作的命令和事物是對的。固然,AFAIK乃至比Redis cluster更嚴格,反而它對相同的鍵允許批量操作。
但是恕我直言依照這類方式,分散的集群帶來分散的效力,并且將這個挑戰(zhàn)帶給了初期的用戶,而且花費了大量的資源,從大量的實例中匯總數(shù)據(jù),得到僅僅是“能用”的結(jié)果,而且你將很快開始有嚴重的負載問題,由于你有太多的時間花費在數(shù)據(jù)的傳輸上。
可是有1些批量操作命令還是支持了的。MGET和DEL是處理的非常好的。有趣的是MGET命令在不同的
服務器之間切分要求并且返回1個結(jié)果。這1點相當酷,或許我以后不能有更好的性能(看以后的吧)。
不管如何,批量操作和事物的不支持的現(xiàn)狀意味著Twemproxy不適用于每一個人,特別像Redis cluster本身。特別是它明顯不支持EVAL(我認為他們應當支持它!它是多通用的,EVAL被設計可以在代理中工作,是由于鍵的名字已明確了)。
有待改進的地方
---
毛病報告機制其實不穩(wěn)定,發(fā)送1個Redis不支持的命令會致使連接被關(guān)閉。比如從redis-cli只發(fā)送1個‘GET‘其實不會報"參數(shù)個數(shù)不正確”的毛病,只會致使連接被掛起。
整體看來,
服務器返回的其它毛病都可以準確的傳給客戶端:
redis metal: 10000 > get list
(毛病)類型操作毛病,鍵匹配了毛病的值類型
另外1個我想要看到的特性是對自動故障恢復的支持。有很多種替換方案:
1) twemproxy已能夠監(jiān)控實例毛病信息、毛病的數(shù)量、在檢測出足夠多的毛病的情況下斷開節(jié)點。但是很遺憾twemproxy不能夠拿從節(jié)點作為替換方案,這樣就能夠發(fā)送1個SLAVE OFNOONE命令來棄用備用節(jié)點,而不用只是斷開毛病節(jié)點。這類情況下twemproxy才是1個具有高可用性的解決方案。
2) 或,我希望twemproxy能夠與Redis Sentinel1起協(xié)同工作,定期檢查Sentinel配置,如果出現(xiàn)故障則更新服務端配置
3) 另外1種替換方案是提供1種熱配置twemproxy的方式,1旦節(jié)點出故障,Redis Sentinel就可以夠切換ASAP代理配置
有很多種替換方案,整體來講,如果能夠提供對HA(高可用性)的底層支持就非常棒了。
性能
---
Twemproxy很快,真的很快,接近直接與Redis通訊的速度。我敢說你用的話最多損失20%的性能。
我對性能唯1的意見是可以有更高效的方法把IMHO MGET命令分發(fā)到實例之間
如果twemproxy與所有Redis實例的延遲很相似的話(很有可能),在MGETs命令在同1時間發(fā)出的情況下,twemproxy很有可能會在同1時間接收到所有節(jié)點的命令,所以我希望看到的是當我在所有實例上運行MGET命令的時候,發(fā)送的數(shù)量和twemproxy接收到的數(shù)量是1致的,但是實際上twemproxy在1秒內(nèi)只接收到了50%的MGET命令。或許是時候重構(gòu)twemproxy的應對模塊了。
結(jié)論
---
這是個偉大的項目,鑒于Redis Cluster還未發(fā)布,我強烈建議有需求的Redis用戶試1下Twemproxy
我正打算將它鏈接到Redis項目網(wǎng)站上,由于我認為Twitter的伙計已用他們的項目為Redis做了不小的貢獻,所以...
這是Twitter贏得榮譽!
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學習有所幫助,可以手機掃描二維碼進行捐贈