您好,登錄后才能下訂單哦!
今天小編給大家分享一下Redis數據分片如何實現的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
Twitter的Twemproxy是目前市面上用的最廣的使用做多的用來做redis集群服務。由于redis是單線程,而且官方的cluster 還不是很穩定和廣泛使用。Twemproxy是一種代理分片機制,Twemproxy作為代理,可接受來自多個程序的訪問,按照路由規則,轉發給后臺的各個Redis服務器,再原路返回。該方案很好的解決了單個Redis實例承載能力的問題。當然,Twemproxy本身也是單點,需要用Keepalived做高可用方案(或者LVS)。通過Twemproxy可以使用多臺服務器來水平擴張redis服務,可以有效的避免單點故障問題。雖然使用Twemproxy需要更多的硬件資源和在redis性能有一定的損失(twitter測試約20%),但是能夠提高整個系統的HA也是相當劃算的。其實twemproxy不光實現了redis協議,還實現了memcached協議,什么意思?換句話說,twemproxy不光可以代理redis,還可以代理memcached。
1)對外暴露一個訪問節點,減少程序復雜度。
2)支持失敗節點自動刪除,可以設置重新連接該節點的時間,可以設置連接多少次之后刪除該節點,該方式適合作為cache存儲,不然會丟失Key;
3)支持設置HashTag,通過HashTag可以自己設定將兩個KEYhash到同一個實例上去。
4)多種hash算法,并且可以設置后端實例的權重。
5)減少與redis的直接連接數:保持與redis的長連接,可設置代理與后臺每個redis連接的數目,自動分片到后端多個redis實例上。
6)避免單點問題:可以平行部署多個代理層,客戶端自動選擇可用的一個。
7)高吞吐量:連接復用,內存復用,將多個連接請求,組成redis pipelining統一向redis請求。
1)不支持針對多個值的操作,比如取sets的子交并補等。
2)不支持Redis的事務操作。
3)對于已申請的內存不會釋放,所有機器內存要大,且需要定期重啟,不然就會出現客戶端連接錯誤。
4)不支持動態增刪節點,修改完配置需重啟。
5)改變節點時,系統不會對已有數據重分配,不自己寫腳本做數據遷移的話,會造成部分key丟失(key本身存在某redis上,只是key被哈希到了其他節點,造成“丟失”)。
6)權重直接影響key的哈希結果,改變節點權重會造成部分key丟失。
7)默認Twemproxy是單線程運行,但是大部分使用Twemproxy的公司都會自行進行二次開發一下,改成多線程。
總體來說,twemproxy還是非常的靠譜,雖然性能有損失,但是相對來說還是很值得的,而且久經考驗,使用非常廣泛。關于更多更加詳細的資料請參考官方文檔。另外twemproxy只適合靜態集群,不適合需要動態增刪節點,手動調整負載的場景,如果我們直接來用,需要做開發改進工作。https://github.com/wandoulabs/codis這個系統基于twemproxy,增加了動態數據遷移等功能,具體使用方法需要進一步測試。
第一種:單節點Twemproxy
ps:節省硬件資源,但容易有單點故障。
第二種:高可用Twemproxy
PS:浪費二分之一的資源,但是節點高可用。
第三種:負載均衡Twemproxy
PS:如果你是大規模Redis或Memcached應用場景,就可以做Twemproxy的負載軍和場景,也就是在高可用Twemproxy的基礎上加LVS節點,利用LVS(Linux virtual server)做Twemproxy的負載均衡,LVS是四層負載均衡技術,有很強大的代理能力,具體可以看本博客的LVS章節介紹。但是當你使用LVS之后,又出現了Twemproxy的問題,單點故障故障問題,這個時候又要跟給LVS做高可用了。但是LVS也支持做負載均衡,利用OSPF路由技術就可以做負載均衡了。而這個架構也就是我目前工作中正在使用的架構方式。
另外不管使用以上哪種架構方式,都無法避免Redis的單點故障問題,Redis持久化也無法避免硬件故障問題。如果必須要保證Redis數據訪問的不可中斷性,那你還是使用Redis集群模式吧,集群模式目前對JAVA支持還不錯,工作中也有大量的使用。
1、下載Twemproxy
git clone https://github.com/twitter/twemproxy.git
2、安裝Twemproxy
Twemproxy需要使用Autoconf進行編譯配置。 GNU Autoconf是一個在Bourne shell下制作供編譯、安裝和打包軟件的配置腳本的工具。Autoconf并不受程序語言限制,常用于C、C++、Erlang和Objective-C。配置腳本控制了一個軟件包在特定系統上的安裝。在進行一系列測試后,配置腳本從模板中生成makefile與頭文件進而調整軟件包,使之適應某一種系統。Autoconf與Automake、Libtool等軟件組成了GNU構建系統。Autoconf由戴維·麥肯思于1991年夏天編寫用于支持他在自由軟件基金會的編程工作。此后,Autoconf包含了多人編寫的改進代碼并成為了使用最廣泛的自由編譯配置軟件。
下面開始使用autoreconf對twemproxy編譯配置:
[root@www twemproxy]# autoreconfconfigure.ac:8: error: Autoconf version 2.64 or higher is required configure.ac:8: the top level autom4te: /usr/bin/m4 failed with exit status: 63 aclocal: autom4te failed with exit status: 63 autoreconf: aclocal failed with exit status: 63 [root@www twemproxy]# autoconf --versionautoconf (GNU Autoconf) 2.63
提示autoreconf 的版本過低,上面使用的是autoconf 2.63版本的,所以下面下載autoconf 2.69版本進行編譯安裝。注意如果你是CentOS6,那么你的默認版本就是2.63,如果你是CentOS7,那么你的默認版本應該是2.69,如果你是Debian8或Ubuntu16,那么你的默認版本應該也是2.69。反正如果執行autoreconf報錯就說明版本低了,需要編譯安裝了。
[root@www ~]# wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz[root@www ~]# tar xvf autoconf-2.69.tar.gz[root@www ~]# cd autoconf-2.69[root@www autoconf-2.69]# ./configure --prefix=/usr[root@www autoconf-2.69]# make && make install[root@www autoconf-2.69]# autoconf --versionautoconf (GNU Autoconf) 2.69
[root@www ~]# cd /root/twemproxy/[root@www twemproxy]# autoreconf -fvi[root@www twemproxy]# ./configure --prefix=/etc/twemproxy CFLAGS="-DGRACEFUL -g -O2" --enable-debug=full[root@www twemproxy]# make && make install
如果autoreconf -fvi時報如下錯誤,就是要安裝libtool工具,需要依賴libtool(如果是CentOS直接使用yum install libtool即可,如果是Debian直接使用apt-get install libtool即可)。
autoreconf: Entering directory `.' autoreconf: configure.ac: not using Gettext autoreconf: running: aclocal --force -I m4 autoreconf: configure.ac: tracing autoreconf: configure.ac: adding subdirectory contrib/yaml-0.1.4 to autoreconf autoreconf: Entering directory `contrib/yaml-0.1.4'autoreconf: configure.ac: not using Autoconf autoreconf: Leaving directory `contrib/yaml-0.1.4' autoreconf: configure.ac: not using Libtool autoreconf: running: /usr/bin/autoconf --force 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/bin/autoconf failed with exit status: 1
[root@www twemproxy]# mkdir /etc/twemproxy/conf[root@www twemproxy]# cat /etc/twemproxy/conf/nutcracker.ymlredis-cluster: listen: 0.0.0.0:22122 hash: fnv1a_64 distribution: ketama timeout: 400 backlog: 65535 preconnect: true redis: true server_connections: 1 auto_eject_hosts: true server_retry_timeout: 60000 server_failure_limit: 3 servers: - 172.16.0.172:6546:1 redis01 - 172.16.0.172:6547:1 redis02
配置選項介紹:
redis-cluster:給這個配置段取一個名字,可以有多個配置段;
listen:設置監控IP和端口端口;
hash:具體的hash函數,支持md5,crc16,crc32,finv1a_32,fnv1a_64,hsieh,murmur,jenkins等十多種,一般選用fnv1a_64可以了,默認也是fnv1a_64;
hash_tag:hash_tag允許根據key的一個部分來計算key的hash值。hash_tag由兩個字符組成,一個是hash_tag的開始,另外一個是hash_tag的結束,在hash_tag的開始和結束之間,是將用于計算key的hash值的部分,計算的結果會用于選擇服務器。例如:如果hash_tag被定義為”{}”,那么key值為”user:{user1}:ids”和”user:{user1}:tweets”的hash值都是基于”user1”,最終會被映射到相同的服務器。而”user:user1:ids”將會使用整個key來計算hash,可能會被映射到不同的服務器。
distribution:指定哈希算法,這個哈希算法決定通過上面hash后的key如何分布在多個server上,默認是”ketama“一致性哈希。ketama:ketama一致性hash算法,會根據服務器構造出一個hash ring,并為ring上的節點分配hash范圍。ketama的優勢在于單個節點添加、刪除之后,會最大程度上保持整個群集中緩存的key值可以被重用。modula:modula非常簡單,就是根據key值的hash值取模,根據取模的結果選擇對應的服務器。random:random是無論key值的hash是什么,都隨機的選擇一個服務器作為key值操作的目標。
timeout:設置twemproxy的超時時間,當timeout被設置后,如果在timeout的時間過后還沒有從服務端得到回應,這時會將超時錯誤信息SERVER_ERROR Connection time out發送給客戶端
backlog:監聽TCP的backlog(連接等待隊列)的長度,默認是512。
preconnect:指定是否在系統啟動時,twemproxy就建立和所有redis的連接,默認是false,一個布爾值;
redis:指定此配置段否作為Redis做代理,如果不加redis為true的話,就可以為memcached集群做代理(這就是Twemproxy作為redis或memcached集群代理的唯一區別);
redis_auth: 如果你的后端Redis開啟了認證,那么就需要redis_auth指定認證的密碼了;
server_connections:twemproxy與每臺redis服務器的連接數,默認就是1,如果大于1,用戶命令可能發到不同的連接上,可能造成命令的實際執行順序和用戶指定的不一致(類似并發);
auto_eject_hosts:是否在節點無法響應的時候剔除,默認為true,但是需要注意,節點剔除后,因為機器數減少,機器哈希位置變化,會造成部分key無法命中,但是不剔除程序連接就會報錯;
server_retry_timeout:控制服務器連接的時間間隔,單位是毫秒,在auto_eject_host被設置為true的時候產生作用,默認是30000毫秒;
server_failure_limit:Redis連續超時的次數,超過這個次數就視其為無法連接,如果auto_eject_hosts設置為true,那么此Redis會被移除;
servers:一個pool中的服務器的地址、端口和權重的列表,包括一個可選的服務器的名字,如果提供服務器的名字,將會使用它決定server的次序,從而提供對應的一致性hash的hash ring。否則,將使用server被定義的次序,可以通過兩種字符串格式指定’host:port:weight’或者’host:port:weight name’。一般都是使用第二種別名的方式,這樣當其中某個Redis節點出現問題時,可以直接添加一個新的Redis節點但服務器名字不要改變,這樣twemproxy還是使用相同的服務器名稱進行hash ring,所以其他數據節點的數據不會出現問題(只有掛點的機器數據丟失)。
PS:要嚴格按照Twemproxy配置文件的格式來,不然就會有語法錯誤;另外,在Twemproxy的配置文件中可以同時設置代理Redis集群或Memcached集群,只需要定義不同的配置段即可。
剛已經加好了配置文件,現在測試下配置文件:
[root@www twemproxy]# /etc/twemproxy/sbin/nutcracker -tnutcracker: configuration file 'conf/nutcracker.yml' syntax is ok
說明配置文件已經成功,現在開始運行nutcracker:
[root@www ~]# /etc/twemproxy/sbin/nutcracker -c /etc/twemproxy/conf/nutcracker.yml -p /var/run/nutcracker.pid -o /var/log/nutcracker.log -d選項說明: -h, –help #查看幫助文檔,顯示命令選項;-V, –version #查看nutcracker版本;-c, –conf-file=S #指定配置文件路徑 (default: conf/nutcracker.yml);-p, –pid-file=S #指定進程pid文件路徑,默認關閉 (default: off);-o, –output=S #設置日志輸出路徑,默認為標準錯誤輸出 (default: stderr);-d, –daemonize #以守護進程運行;-t, –test-conf #測試配置腳本的正確性;-D, –describe-stats #打印狀態描述;-v, –verbosity=N #設置日志級別 (default: 5, min: 0, max: 11);-s, –stats-port=N #設置狀態監控端口,默認22222 (default: 22222);-a, –stats-addr=S #設置狀態監控IP,默認0.0.0.0 (default: 0.0.0.0);-i, –stats-interval=N #設置狀態聚合間隔 (default: 30000 msec);-m, –mbuf-size=N #設置mbuf塊大小,以bytes單位 (default: 16384 bytes);
PS:一般在生產環境中,都是使用進程管理工具來進行twemproxy的啟動管理,如supervisor或pm2工具,避免當進程掛掉的時候能夠自動拉起進程。
[root@www ~]# ps aux | grep nutcrackerroot 20002 0.0 0.0 19312 916 ? Sl 18:48 0:00 /etc/twemproxy/sbin/nutcracker -c /etc/twemproxy/conf/nutcracker.yml -p /var/run/nutcracker.pid -o /var/log/nutcracker.log -d root 20006 0.0 0.0 103252 832 pts/0 S+ 18:48 0:00 grep nutcracker [root@www ~]# netstat -nplt | grep 22122tcp 0 0 0.0.0.0:22122 0.0.0.0:* LISTEN 20002/nutcracker
這里我們使用第一種方案在同一臺主機上測試Twemproxy代理Redis集群,一個twemproxy和兩個Redis節點(想添加更多的也可以)。Twemproxy就是用上面的配置了,下面只需要增加兩個Redis節點。
在安裝Redis之前,需要安裝Redis的依賴程序tcl,如果不安裝tcl在Redis執行make test的時候就會報錯的哦。
[root@www ~]# yum install -y tcl[root@www ~]# wget https://github.com/antirez/redis/archive/3.2.0.tar.gz[root@www ~]# tar xvf 3.2.0.tar.gz -C /usr/local[root@www ~]# cd /usr/local/[root@www local]# mv redis-3.2.0 redis[root@www local]# cd redis[root@www redis]# make[root@www redis]# make test[root@www redis]# make install
[root@www ~]# mkdir /data/redis-6546[root@www ~]# mkdir /data/redis-6547[root@www ~]# cat /data/redis-6546/redis.confdaemonize yes pidfile /var/run/redis/redis-server.pid port 6546bind 0.0.0.0 loglevel notice logfile /var/log/redis/redis-6546.log [root@www ~]# cat /data/redis-6547/redis.confdaemonize yes pidfile /var/run/redis/redis-server.pid port 6547bind 0.0.0.0 loglevel notice logfile /var/log/redis/redis-6547.log
PS:簡單提供兩個Redis配置文件,如果開啟了Redis認證,那么在twemproxy中也需要填寫Redis密碼。
[root@www ~]# /usr/local/redis/src/redis-server /data/redis-6546/redis.conf[root@www ~]# /usr/local/redis/src/redis-server /data/redis-6547/redis.conf[root@www ~]# ps aux | grep redisroot 23656 0.0 0.0 40204 3332 ? Ssl 20:14 0:00 redis-server 0.0.0.0:6546 root 24263 0.0 0.0 40204 3332 ? Ssl 20:16 0:00 redis-server 0.0.0.0:6547
首先twemproxy配置項中servers的主機要配置正確,然后連接Twemproxy的22122端口即可測試。
[root@www ~]# redis-cli -p 22122127.0.0.1:22122> set key vlaue OK 127.0.0.1:22122> get key"vlaue"127.0.0.1:22122> FLUSHALL Error: Server closed the connection 127.0.0.1:22122> quit
上面我們set一個key,然后通過twemproxy也可以獲取到數據,一切正常。但是在twemproxy中使用flushall命令就不行了,不支持。
然后我們去找分別連接兩個redis節點,看看數據是否出現在某一個節點上了,如果有,就說明twemproxy正常運行了。
[root@www ~]# redis-cli -p 6546127.0.0.1:6546> get key (nil) 127.0.0.1:6546>
由上面的結果我們可以看到,數據存儲到6547節點上了。目前沒有很好的辦法明確知道某個key存儲到某個后端節點了。
由于twemproxy沒有提供啟動腳本,都是命令行參數啟動的。所以,無法使用對twemproxy進行reload的操作,在生產環境中,一個應用無法reload(重載配置文件)是一個災難。當你對twemproxy進行增刪節點時如果直接使用restart的話勢必會影響線上的業務。所以最好的辦法還是reload,既然twemproxy沒有提供,那么可以使用kill命令帶一個信號,然后跟上twemproxy主進程的進行號即可。
kill -SIGHUP PID
注意,PID就是twemproxy master進程。
以上就是“Redis數據分片如何實現”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。