Twemproxy 又稱nutcracker ,是一個memcache、Redis協議的輕量級代理,一個用於sharding 的中介軟體。有了Twemproxy,客戶端不直接訪問Redis伺服器,而是通過twemproxy 代理中介軟體間接訪問。 Twemproxy 為 Twitter 開源產品,簡單來說,Twemproxy是Twitter開發的一個redis代理proxy,類似於nginx的反向代理或者mysql的代理工具,如amoeba。Twemproxy通過引入一個代理層,可以將其後端的多臺Redis或Memcached例項進行統一管理與分配,使應用程式只需要在Twemproxy上進行操作,而不用關心後面具體有多少個真實的Redis或Memcached儲存。
一般來說,只要伺服器上執行了Redis,那麼就有可能造成一種非常可怕局面:伺服器的記憶體將立刻被佔滿,而且一臺Redis資料庫的效能終歸是有限制的,那麼現在如果要求保證使用者的執行速度快,就需要使用叢集的設計。而對於叢集的設計主要的問題就是解決單例項Redis的效能瓶頸。
Twemproxy是一個專門為了這種nosql資料庫設計的一款代理工具軟體,這個工具軟體最大的特徵是可以實現資料的分片處理。所謂的分片指的是根據一定的演算法將要儲存的資料儲存到不同的節點之中。 有了分片之後資料的儲存節點就可能有無限多個,但是理論上如果要真進行叢集的搭建,往往要求三臺節點起步。Twemproxy代理機制具有如下特點:
1)支援失敗節點自動刪除 可以設定重新連線該節點的時間 可以設定連線多少次之後刪除該節點 2)支援設定HashTag 通過HashTag可以自己設定將兩個key雜湊到同一個例項上去 3)減少與redis的直接連線數 保持與redis的長連線 減少了客戶端直接與伺服器連線的連線數量 4)自動分片到後端多個redis例項上 多種hash演算法:md5、crc16、crc32 、crc32a、fnv1_64、fnv1a_64、fnv1_32、fnv1a_32、hsieh、murmur、jenkins 多種分片演算法:ketama(一致性hash演算法的一種實現)、modula、random 可以設定後端例項的權重 5)避免單點問題 可以平行部署多個代理層,通過HAProxy做負載均衡,將redis的讀寫分散到多個twemproxy上。 6)支援狀態監控 可設定狀態監控ip和埠,訪問ip和埠可以得到一個json格式的狀態資訊串 可設定監控資訊重新整理間隔時間 7)使用 pipelining 處理請求和響應 連線複用,記憶體複用 將多個連線請求,組成reids pipelining統一向redis請求 8)並不是支援所有redis命令 不支援redis的事務操作 使用SIDFF, SDIFFSTORE, SINTER, SINTERSTORE, SMOVE, SUNION and SUNIONSTORE命令需要保證key都在同一個分片上。
舉個小例子:
你可以把公司前臺的MM看作一個proxy,你是個送快遞的,你可以通過這個妹子替你代理把你要送達的包裹給公司內部的人,而你不用知道公司每個人座位在哪裡。 Twemproxy可以把多臺redis server當作一臺使用,開發人員通過twemproxy訪問這些redis servers 的時候不用關心到底去哪一臺redis server讀取 k-v資料或者把k-v資料更新到資料集中。
通過Twemproxy可以使用多臺伺服器來水平擴張redis服務,可以有效的避免單點故障問題。雖然使用Twemproxy需要更多的硬體資源和在redis效能有一定的損失(twitter測試約20%),但是能夠提高整個系統的HA也是相當划算的。比如我所在的公司,只使用一臺redis server進行讀寫,但是還有一臺slave server一直在同步這臺生產伺服器的資料。這樣做就是為了防止這臺單一的生產伺服器出現故障時能夠有一個"備胎",可以把前端的redis資料讀寫請求切換到從伺服器上,web程式因而不需要直接去訪問mysql資料庫。再借助於haproxy(又是proxy)或者VIP技術可以實現一個簡單的HA方案,可以避免單點故障。但是這種簡單的Master-Slave"備胎"方案不能擴張整個redis的容量(如果用系統記憶體大小衡量,且不考慮記憶體不足時把資料swap到磁碟上),最大容量由所有的redis servers中最小記憶體決定的【木桶的短板】。
Twemproxy可以把資料sharding(碎片,這裡是分散的意思)到多臺伺服器的上,每臺伺服器儲存著整個資料集的一部分。因而,當某一臺redis伺服器當機了,那麼也就失去了一部分資料。如果藉助於redis的master-slave replication,能保證在任何一臺redis不能工作情況下,仍然能夠保證能夠存在一個整個資料集的完全覆蓋,那麼整個redis group(或者稱作cluster)仍然能夠正常工作。
需要注意的是:
Twemproxy不會增加Redis的效能指標資料,據業界測算,使用twemproxy相比直接使用Redis會帶來大約10%的效能下降。但是單個Redis程式的記憶體管理能力有限。據測算,單個Redis程式記憶體超過20G之後,效率會急劇下降。目前,建議單個Redis最好配置在8G以內;8G以上的Redis快取需求,通過Twemproxy來提供支援。
-----------------------------------------------------------------------------------------------------------------------------------------------------
下面記錄下Redis+Twemproxy(nutcracker)叢集部署過程:
先簡單看下叢集架構
Twemproxy可以把多臺redis server當作一臺使用,擴大整個redis的容量,開發人員通過twemproxy訪問這些redis servers 的時候不用關心到底去哪一臺redis server讀取k-v資料或者把k-v資料更新到資料集中。
1)叢集環境 182.48.115.236 twemproxy-server 安裝nutcracker 182.48.115.237 redis-server1 安裝redis 182.48.115.238 redis-server2 安裝redis 如果線上上使用的話: 中間代理層twemproxy需要2臺,並且需要結合keepalived(心跳測試)實現高可用,客戶端通過vip資源訪問twemproxy。 另外,後面的redis節點也都要做主從複製環境。因為twemproxy會將資料碎片到每個redis節點上,如果節點掛了,那部分資料就沒了。所以最好對每個redis節點機做主從,防止資料丟失。 這裡做測試,我只使用一臺twemproxy+2個redis節點(不做主從)。 關閉三臺機器的iptables防火牆和selinux 2)在兩臺redis機器上安裝並啟動redis 可以參考:http://www.cnblogs.com/kevingrace/p/6265722.html 3)在twemproxy-server機器上安裝nutcracker 編譯安裝autoconf [root@twemproxy-server ~]# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz [root@twemproxy-server ~]# tar -zvxf autoconf-2.69.tar.gz [root@twemproxy-server ~]# cd autoconf-2.69 [root@twemproxy-server autoconf-2.69]# ./configure && make && make install 編譯安裝automake [root@twemproxy-server ~]# wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz [root@twemproxy-server ~]# tar -zvxf automake-1.15.tar.gz [root@twemproxy-server ~]# cd automake-1.15 [root@twemproxy-server automake-1.15]# ./configure && make && make install 編譯安裝libtool [root@twemproxy-server ~]# wget https://ftp.gnu.org/gnu/libtool/libtool-2.4.6.tar.gz [root@twemproxy-server ~]# tar -zvxf libtool-2.4.6.tar.gz [root@twemproxy-server ~]# cd libtool-2.4.6 [root@twemproxy-server libtool-2.4.6]# ./configure && make && make install 編譯安裝twemproxy [root@twemproxy-server ~]# wget https://github.com/twitter/twemproxy/archive/master.zip [root@twemproxy-server ~]# unzip master.zip [root@twemproxy-server ~]# cd twemproxy-master [root@twemproxy-server twemproxy-master]# aclocal [root@twemproxy-server twemproxy-master]# autoreconf -f -i -Wall,no-obsolete //執行autoreconf 生成 configure檔案等 [root@twemproxy-server twemproxy-master]# ./configure --prefix=/usr/local/twemproxy/ [root@twemproxy-server twemproxy-master]# make && make install ................................................................................. 注意:如果沒有安裝libtool 的話,autoreconf 的時候會報錯,如下: configure.ac:133: the top level configure.ac:36: error: possibly undefined macro: AC_PROG_LIBTOOL If this token and others are legitimate, please use m4_pattern_allow. See the Autoconf documentation. autoreconf: /usr/local/bin/autoconf failed with exit status: 1 ................................................................................. twemproxy配置: [root@twemproxy-server ~]# cd /usr/local/twemproxy/ [root@twemproxy-server twemproxy]# ls sbin share [root@twemproxy-server twemproxy]# cp -r /root/twemproxy-master/conf /usr/local/twemproxy/ [root@twemproxy-server twemproxy]# cd conf/ [root@twemproxy-server conf]# ls nutcracker.leaf.yml nutcracker.root.yml nutcracker.yml [root@twemproxy-server conf]# cp nutcracker.yml nutcracker.yml.bak [root@twemproxy-server conf]# vim nutcracker.yml alpha: //這個名稱可以自己隨意定義 listen: 182.48.115.236:22121 hash: fnv1a_64 distribution: ketama auto_eject_hosts: true redis: true server_retry_timeout: 2000 server_failure_limit: 1 servers: //這裡配置了兩個分片 - 182.48.115.237:6379:1 - 182.48.115.238:6379:1 [root@twemproxy-server conf]# nohup /usr/local/twemproxy/sbin/nutcracker -c /usr/local/twemproxy/conf/nutcracker.yml & [root@twemproxy-server conf]# ps -ef|grep nutcracker root 6407 24314 0 23:26 pts/0 00:00:00 /usr/local/twemproxy/sbin/nutcracker -c /usr/local/twemproxy/conf/nutcracker.yml root 6410 24314 0 23:26 pts/0 00:00:00 grep nutcracker [root@twemproxy-server conf]# lsof -i:22121 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nutcracke 6407 root 5u IPv4 155109 0t0 TCP localhost:22121 (LISTEN) 4)測試 twemproxy set/get ,後端分片檢視 [root@twemproxy-server ~]# redis-cli -h 182.48.115.236 -p 22121 182.48.115.236:22121> 測試短key - value [root@twemproxy-server ~]# redis-cli -h 182.48.115.236 -p 22121 182.48.115.236:22121> set wangshibo 666666 OK 182.48.115.236:22121> get wangshibo "666666" 測試長key - value 182.48.115.236:22121> set huihuihuihuihuihui "hahahahahahahahhahahahahahahahhahahahahahah" OK 182.48.115.236:22121> get huihuihuihuihuihui "hahahahahahahahhahahahahahahahhahahahahahah" 登入兩臺redis節點上檢視,發現已經有分片了 [root@redis-server1 ~]# redis-cli -h 182.48.115.237 -p 6379 182.48.115.237:6379> get wangshibo "666666" 182.48.115.237:6379> get huihuihuihuihuihui "hahahahahahahahhahahahahahahahhahahahahahah" [root@redis-server2 ~]# redis-cli -h 182.48.115.238 -p 6379 182.48.115.238:6379> get wangshibo "666666" 182.48.115.238:6379> get huihuihuihuihuihui "hahahahahahahahhahahahahahahahhahahahahahah"