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