twemproxy背景 在業務量劇增的今天,單台高速緩存伺服器已經無法滿足業務的需求, 而相較於大容量SSD數據存儲方案,緩存具備速度和成本優勢,但也存在數據安全性的挑戰。為此搭建一個高速緩存伺服器集群來進行分散式存儲是十分必要的。 目前主流的高速緩存伺服器是redis和memchache。而twe ...
twemproxy背景
在業務量劇增的今天,單台高速緩存伺服器已經無法滿足業務的需求, 而相較於大容量SSD數據存儲方案,緩存具備速度和成本優勢,但也存在數據安全性的挑戰。為此搭建一個高速緩存伺服器集群來進行分散式存儲是十分必要的。
目前主流的高速緩存伺服器是redis和memchache。而twemproxy是支持memcached和redis協議的輕量級代理中間件,能用於高速緩存伺服器集群的搭建。為此,twemproxy是高速緩存伺服器集群的核心組件之一,也是業界較為成熟的高速緩存伺服器集群解決方案之一。
twemproxy概述
twemproxy是搭建分散式緩存集群的重要組件之一。他能將來自客戶端的redis包通過key分片發送到不同的redis伺服器,而不是發到單個redis伺服器上。因此,可以使本來集中到一個redis上的信息被分流到多個redis上,這就使得 twemproxy能支持redis集群。
不難想到,因為twemproxy的分片功能,可以輕鬆地對redis集群進行水平擴展(簡單地理解成在一個業務中加入更多的redis伺服器),同時對於代碼稍加改造,我們就可以得到能讀寫分離的redis集群,這大大將提高了redis集群的性能。這使得各大公司如豌豆莢、阿裡、百度等都對於這份代碼進行了修改,能使其滿足分散式緩存集群的要求。當然,twemproxy並不負責數據一致性的工作。
源碼下載地址:https://github.com/twitter/twemproxy/
twemproxy架構
為了能更好地瞭解twemproxy的代碼結構,我們就需要瞭解twemproxy的架構,明白與它交互的組件。下麵就是一般twemproxy的架構圖
圖1 twemproxy架構圖
圖1中,client是客戶端,這裡的客戶端可以是很多應用,如網頁,也可以是一些需要redis支持的伺服器。LVS是Linux虛擬伺服器,它主要用於負載均衡以及數據冗餘,當然這一個層的負載均衡以及數據冗餘也可以通過其他手段完成,如HAproxy等,當然也可以不需要這一層,可以讓客戶端直連twemproxy。memchache和redis是twemproxy目前支持的兩種高速緩存伺服器,但是考慮到高可用性和具體功能,一般會選用redis伺服器。
我們可以看到在這種架構下,由於所有的通信都是用redis或者memchache協議完成。為此,client根本不知道和它通信的是高速緩存伺服器還是twemproxy,高速緩存伺服器memchache或redis也不知道和它聯繫的的是client還是twemproxy。
這樣業務量一旦提升,我們只需要添加適量的高速緩存伺服器和twemproxy伺服器就可以滿足業務需求。在這期間,幾乎不需要對原先的client端的代碼或者原先的高速緩存伺服器的配置做任何修改,就可以完成業務上的水平擴容,這樣就大大提高了高速緩存伺服器的可用性。同時,由於不用修改client端的代碼,我們可以進行平滑升級,即用戶根本感知不到我們對業務進行了擴容,線上的client端不會因為我們的擴容而停止服務。同樣地,我們可以對業務進行縮容處理。因此在業務量急劇變化的時候,這種架構的靈活性和可用性是原先單一的高速緩存伺服器集群不能比擬的。
從這幅架構圖上,我們也能開始逐一說明twemproxy的特性,閱讀源碼文件夾下的《README.md》的features,至於他是如何實現的,就需要我們去解讀代碼,這不是這一章要完成的任務。
圖2 twemproxy特性
1.Fast,即快速,據測試,直連twenproxy和直連redis相比幾乎沒有性能損失,這已經很逆天了,最重要的是他還沒有進行讀寫分離就能達到這樣的效果,確實fast
2.Lightweight,即輕量級,就我個人而言,它代碼量就是輕量級的,解壓後僅僅1.8MB!!!!因為透明連接池,記憶體零拷貝以及epoll模型的使用,使得它足夠快速和輕量級。
3.Enables pipelining of requests and responses,Keeps connection count on the backend caching servers low,即保持前端的連接數,減少後端的連接數,這裡主要得益於透明連接池的使用,前端主要指的是client和lvs,後端指的是redis和memchache,這個好處特別明顯,既可以減少了redis的連接負載,又保持了保持了前端的功能。
4.Enables pipelining of requests and responses,即將請求和回覆管道化,這裡我的理解是他將請求包和回覆包一一對應起來後,使得它的請求和回覆更明確。
5.Supports multiple server pools simultaneously,Shard data automatically across multiple servers,即它可以支持多個高速緩存伺服器,以及能對高速緩存伺服器的數據進行共用,這是通過我在前面講到過twemproxy的分片功能來實現的。
6.Implements the complete memcached ascii and redis protocol,它支持memchache和redis這兩個協議,當然現在只支持其中大部分的協議而不是全部,這個會在後面開章節專門說明。
7.Supports multiple hashing modes including consistent hashing and distribution.就是它支持很多哈希演算法來哈希key,如crc32,crc16,MD5等等。
8.Easy configuration of server pools through a YAML file.它的配置文件是通過YAML文件來配置的,YAML文件好處是簡單易懂,容易學習配置。
9.Can be configured to disable nodes on failures. 它會自動指出連接失敗的節點並報警,就是一旦某個高速緩存伺服器發生故障,它能感知到並報警。
10.Observability via stats exposed on the stats monitoring port.這是他的監控功能,一般比較少用,但是它提示的信息卻有統計的價值,如統計發送了多少讀寫命令。
通過上述的功能分析,我們可以理出一個我們值得關註的實現上的功能列表:
1.記憶體管理,這是導致特性1和4的關鍵之一,他通過一些方法,如記憶體用完後不立即釋放將其放入記憶體隊列里以備它用,記憶體零拷貝等手段使記憶體使用效率大幅提高。對應源碼中的nc_mbuf 文件。
2.透明連接池,這是導致特性1,3的關鍵之一,當然連接池內的連接同樣的是使用完後不立即釋放將其放入連接隊列里以備它用。對應源碼中的nc_connection 文件。
3.分片,這是導致特性5,6的關鍵,也是twenproxy的核心功能。當然後面的7,8也導致了分片能得以進行。對應源碼中的proto文件夾、hashkit文件夾。
4.配置文件,這影響了特性8,同時這份代碼在配置上的代碼風格非常簡約,對應源碼中的nc_conf 文件。
5.監控,不是特別瞭解但是它完成了9,10特性,對應源碼中的nc_proxy 、nc_stats 文件。
這些將是我們未來閱讀剖析代碼的一些重要關註點。
twemproxyLinux下安裝
通過上述的描述,大家是否心動了,想要玩一下twemproxy,那麼請大家與我一起安裝twemproxy,當然安裝twemproxy對於我們閱讀twemproxy源碼也會有所幫助。
1.首先安裝autoconf2.69,這個請參考我的博文http://www.cnblogs.com/onlyac/p/5408420.html
2.進入源碼目錄
cd twemproxy
3.使用autoconf進行編譯準備
autoreconf -fvi
./configure CFLAGS="-g -gstabs -O3 -fno-strict-aliasing" --enable-debug=full
4.編譯以及安裝
make && make install
這樣編譯以及安裝完的程式nutcracker已在src目錄下生成了。
未來我們也可以採用通過gdb來進行邊走流程邊看代碼的一種閱讀代碼方式。
總結
在這篇文章中,我們首先概述了twemproxy,接著通過架構圖展示,我們分析了該架構的優點,提取了會成為我們閱讀源碼的一些重要關註點和twemproxy的工作環境,最後闡述瞭如何安裝twemproxy。