Redis3.0 最大的特點就是有了cluster的能力,使用redis-trib.rb工具可以輕松構建Redis Cluster。Redis Cluster采用無中心結構,每個節(jié)點保存數(shù)據(jù)和整個集群狀態(tài),每個節(jié)點都和其他所有節(jié)點連接。節(jié)點之間使用gossip協(xié)議傳播信息以及發(fā)現(xiàn)新節(jié)點,這種結構和Cassandra很相似,Cassandra節(jié)點可以轉發(fā)請求。Redis集群中節(jié)點不作為client請求的代理,client根據(jù)node返回的錯誤信息重定向請求。一、集群特性1.數(shù)據(jù)可以在cluster的多個node之間進行共享;2.一次請求處理多批key的命令將不再被支持,因為這些命令處理的key可能在不同的node之間,使用了它們反而會降低cluster的性能;3.提供高HA,即某個node failed后cluster依舊提供高可用性。cluster提供如下能力保證:1.在cluster內自動把數(shù)據(jù)劃分到不同的set上;2.當集群中一小群機器出現(xiàn)網絡故障時或者其他種類的failure時,cluster要保證系統(tǒng)繼續(xù)可用;redis的每個node啟動后占用兩個port 6379 & 16379。redis通過port 6379繼續(xù)對client提供服務,client通過redis獨有的文本協(xié)議與node進行通信,所以這個port被成為client port or command port。redis node通過port 16379與cluster內部的其他node進行二進制形式的通信,所以被稱為data port or bus port。通過port 16379,node之間進行 failure detection(探活)、configure update(配置更新)、failure authorization(失敗確認)。如果node使用別的端口作為command port,那么data port 一定是command port + 10000。兩個不同的cluster之間也可以通過data port進行data migration。二、分片redis cluster內部沒用提供一致性hash算法來保證集群的可伸縮能力,而是通過簡單的crc16 hash算法來進行sharding,所以它最多提供16384個slot。如果cluster有三個node,分別為 A and B and C,則A負責0 - 5500 slots,B負責5501 - 11000 slots,C負責11001 - 16383 slots。進行擴容的時候,就得在不同的node之間進行slots的遷移,不需要關機,也不會出現(xiàn)服務不可用現(xiàn)象。cluster內部每個node(也成為一個instance)由一個master和多個slave構成,當master fail的時候,可以通過選舉機制選出一個slave代替master。Redis Cluster不提供強一致性。例如cluster接受了一個寫請求,給client返回ok,這個寫請求的內容也可能丟失。因為其寫流程如下:1 master B接受了一個寫請求;2 B寫成功,返回ok給client;3 B把數(shù)據(jù)廣播給slaves(B1、B2、B3)如果第二步執(zhí)行完畢后,B crash了,則會發(fā)生數(shù)據(jù)不一致現(xiàn)象。這與傳統(tǒng)的DBMS類似,它們接收了寫請求后,每隔1S才會把數(shù)據(jù)寫入disk,這么做也是在性能和一致性之間做一個平衡。如果用戶對數(shù)據(jù)的一致性要求比較高,Redis可能也會兼顧這種需求,將來會提供相應的選項,讓redis中的slave沒用成功的接受數(shù)據(jù)之前不會給client返回ok給client。即先執(zhí)行step 3,然后再執(zhí)行step 2。一致性還有一種場景。假設有client Z,與cluster內各個node A and B and C,以及各個node的replica A1 and B1 and C1,Z與B之間連接正常,但是B與B1以及cluster內其他nodes連接失敗。如果Z發(fā)起write request,那么B會給他返回ok,但是B1無法獲取到相應的數(shù)據(jù),這就要求寫的時候也要把node與cluster內其他的成員的探活也要考慮在內。基本要求就是,寫時間周期要大于探活時間周期(node timeout)。當node B timeout之后,master B會自動進入failing狀態(tài),拒絕外部client的連接請求,而cluster則會選出slave B1來代替B。三、安裝配置
1.環(huán)境使用2臺centos服務器,每臺機器上部署3個實例,集群為三個主節(jié)點與三個從節(jié)點:192.168.36.54:6380192.168.36.54:6381192.168.36.54:6382192.168.36.189:6380192.168.36.189:6381192.168.36.189:6382
2.安裝依賴
由于通過Redis-trib.rb工具構建Redis Cluster,需要rudy環(huán)境,執(zhí)行如下命令安裝:yum -y install zlib ruby rubygems安裝ruby 的redis庫:gem install redis
3.安裝redis 3.0
wget http://download.redis.io/releases/redis-3.0.0.tar.gztar -zxvf redis-3.0.0.tar.gzmkdir rediscd redis-3.0.0make PREFIX=/home/slim/redismake PREFIX=/home/slim/redis install將集群工具復制到/home/slim/redis/bin下cp /home/slim/redis-3.0.0/src/redis-trib.rb ./bin/創(chuàng)建數(shù)據(jù)配置目錄mkdir -p /home/slim/redis/{conf,data,logs}
4.配置
在2臺機器上配置如下:
cd /home/slim/rediscp /home/slim/redis-3.0.0/redis.conf ./conf/redis-6380.conf cp /home/slim/redis-3.0.0/redis.conf ./conf/redis-6381.conf cp /home/slim/redis-3.0.0/redis.conf ./conf/redis-6382.conf
修改配置:
[plain] view plain copy print?
#基本配置 daemonize yes pidfile /home/slim/redis/data/redis-6380.pid port 6380 bind 192.168.36.189 unixsocket /home/slim/redis/data/redis-6380.sock unixsocketperm 700 timeout 300 loglevel verbose logfile /home/slim/redis/logs/redis-6380.log databases 16 dbfilename dump-6380.rdb dir /home/slim/redis/data/ #aof持久化 appendonly yes appendfilename appendonly-6380.aof appendfsync everysec no-appendfsync-on-rewrite yes auto-aof-rewrite-percentage 80-100 auto-aof-rewrite-min-size 64mb lua-time-limit 5000 #集群配置 cluster-enabled yes cluster-config-file /home/slim/redis/data/nodes-6380.conf cluster-node-timeout 5000 每個實例配置類似,修改一下都應端口、IP地址、文件名稱即可。
Redis集群由多個運行在集群模式(cluster%20mode)下的Redis實例組成,實例的集群模式需要通過配置來開啟,開啟集群模式的實例將可以使用集群特有的功能和命令。要讓集群正常運作至少需要三個主節(jié)點,%20不過在剛開始試用集群功能時,%20強烈建議使用六個節(jié)點:%20其中三個為主節(jié)點,%20而其余三個則是各個主節(jié)點的從節(jié)點。cluster-enabled:開實例的集群模式cluster-conf-file:設定了保存節(jié)點配置文件的路徑,默認值為nodes.conf。節(jié)點配置文件無須人為修改,它由Redis集群在啟動時創(chuàng)建,并在有需要時自動進行更新。cluster-node-timeout:集群節(jié)點互連超時的閥值
5.啟動服務1)啟動2臺機器實例
./bin/redis-server%20./conf/redis-6380.conf%20;tail%20-f%20logs/redis-6380.log
./bin/redis-server%20./conf/redis-6381.conf%20;tail%20-f%20logs/redis-6381.log
./bin/redis-server%20./conf/redis-6382.conf%20;tail%20-f%20logs/redis-6382.log
啟動日志中打印:“8591:M%2011%20Apr%2022:20:46.134%20*%20No%20cluster%20configuration%20found,%20I'm%2083fc65283bbbb71b4c089337df05594d67f4cab6”每個節(jié)點都使用%20ID%20而不是%20IP%20或者端口號來記錄其他節(jié)點,%20因為%20IP%20地址和端口號都可能會改變,%20而這個獨一無二的標識符(identifier)則會在節(jié)點的整個生命周期中一直保持不變。
查看啟動進程:
[plain] view%20plain copy print?![在CODE上查看代碼片]()
ps -ef | grep redis slim 8525 1 0 22:16 ? 00:00:01 ./bin/redis-server 192.168.36.54:6380 [cluster] slim 8544 1 0 22:17 ? 00:00:00 ./bin/redis-server 192.168.36.54:6381 [cluster] slim 8591 1 0 22:20 ? 00:00:00 ./bin/redis-server 192.168.36.54:6382 [cluster] 2)集群配置
在每臺機器上啟動的redis服務都是相互獨立,下面我們就使用redis-trib.rb工具構建Redis%20Cluster。
./bin/redis-trib.rb%20create%20--replicas%201%20 192.168.36.54:6380%20192.168.36.54:6381%20192.168.36.54:6382%20192.168.36.189:6380%20192.168.36.189:6381%20192.168.36.189:6382
命令的意義如下:給定%20redis-trib.rb%20程序的命令是%20create%20,%20這表示我們希望創(chuàng)建一個新的集群。選項%20--replicas%201%20表示我們希望為集群中的每個主節(jié)點創(chuàng)建一個從節(jié)點。之后跟著的其他參數(shù)則是實例的地址列表,%20我們希望程序使用這些地址所指示的實例來創(chuàng)建新集群。簡單來說,%20以上命令的意思就是讓%20redis-trib%20程序創(chuàng)建一個包含三個主節(jié)點和三個從節(jié)點的集群。
啟動日志:
[plain] view%20plain copy print?![在CODE上查看代碼片]()
>>> Creating cluster Connecting to node 192.168.36.54:6380: OK Connecting to node 192.168.36.54:6381: OK Connecting to node 192.168.36.54:6382: OK Connecting to node 192.168.36.189:6380: OK Connecting to node 192.168.36.189:6381: OK Connecting to node 192.168.36.189:6382: OK >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 192.168.36.54:6380 192.168.36.189:6380 192.168.36.54:6381 Adding replica 192.168.36.189:6381 to 192.168.36.54:6380 Adding replica 192.168.36.54:6382 to 192.168.36.189:6380 Adding replica 192.168.36.189:6382 to 192.168.36.54:6381 M: f6285c8a7506b224840d7b26b2b5d1671320c21f 192.168.36.54:6380 slots:0-5460 (5461 slots) master M: 26ce71d626175f88e0416e3f45b2bfb29304c7b3 192.168.36.54:6381 slots:10923-16383 (5461 slots) master S: 83fc65283bbbb71b4c089337df05594d67f4cab6 192.168.36.54:6382 replicates b1a15a3cd14ea65671a7134850e17b8919a17da5 M: b1a15a3cd14ea65671a7134850e17b8919a17da5 192.168.36.189:6380 slots:5461-10922 (5462 slots) master S: 1080e423a55a2c24dae649dac03ffa09ed26d3e8 192.168.36.189:6381 replicates f6285c8a7506b224840d7b26b2b5d1671320c21f S: de4302f43ff89843675446396552fd19f741246a 192.168.36.189:6382 replicates 26ce71d626175f88e0416e3f45b2bfb29304c7b3 Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join... >>> Performing Cluster Check (using node 192.168.36.54:6380) M: f6285c8a7506b224840d7b26b2b5d1671320c21f 192.168.36.54:6380 slots:0-5460 (5461 slots) master M: 26ce71d626175f88e0416e3f45b2bfb29304c7b3 192.168.36.54:6381 slots:10923-16383 (5461 slots) master M: 83fc65283bbbb71b4c089337df05594d67f4cab6 192.168.36.54:6382 slots: (0 slots) master replicates b1a15a3cd14ea65671a7134850e17b8919a17da5 M: b1a15a3cd14ea65671a7134850e17b8919a17da5 192.168.36.189:6380 slots:5461-10922 (5462 slots) master M: 1080e423a55a2c24dae649dac03ffa09ed26d3e8 192.168.36.189:6381 slots: (0 slots) master replicates f6285c8a7506b224840d7b26b2b5d1671320c21f M: de4302f43ff89843675446396552fd19f741246a 192.168.36.189:6382 slots: (0 slots) master replicates 26ce71d626175f88e0416e3f45b2bfb29304c7b3 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. 從啟動日志可以看出有6個集群實例,主節(jié)點為:192.168.36.54:6380192.168.36.189:6380192.168.36.54:6381每個主節(jié)點對應一個從節(jié)點Adding%20replica%20192.168.36.189:6381%20to%20192.168.36.54:6380Adding%20replica%20192.168.36.54:6382%20to%20192.168.36.189:6380Adding%20replica%20192.168.36.189:6382%20to%20192.168.36.54:6381slots劃分:192.168.36.54:6380%20 %200-5460192.168.36.189:6380%20 5461-10922192.168.36.54:6381%20 %2010923-16383一共16384%20slots注:redis-trib.rb使用參數(shù)
[plain] view%20plain copy print?![在CODE上查看代碼片]()
Usage: redis-trib <command> <options> <arguments ...> fix host:port call host:port command arg arg .. arg check host:port import host:port --from <arg> set-timeout host:port milliseconds add-node new_host:new_port existing_host:existing_port --master-id <arg> --slave reshard host:port --to <arg> --from <arg> --slots <arg> --yes create host1:port1 ... hostN:portN --replicas <arg> help (show this help) del-node host:port node_id For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster. 參數(shù)說明:call:執(zhí)行redis命令create:創(chuàng)建一個新的集群。host1:port1%20...%20hostN:portN指定了用于構建Redis%20Cluster的所有redis實例,節(jié)點角色由順序決定,先master之后是slave。而--replicas%20則指定了為Redis%20Cluster中的每個Master節(jié)點配備幾個Slave節(jié)點。add-node%20 將一個節(jié)點添加到集群里面,%20第一個是新節(jié)點ip:port,%20第二個是任意一個已存在節(jié)點ip:port,--master-id reshard:重新分片check:查看集群信息del-node:移除一個節(jié)點對于客戶端redis-cli要訪問集群,在啟動的時候需要添加一個-c參數(shù),如查看集群所有節(jié)點:[plain] view%20plain copy print?![在CODE上查看代碼片]()
./bin/redis-cli -c -h 192.168.36.189 -p 6380 cluster nodes 1080e423a55a2c24dae649dac03ffa09ed26d3e8 192.168.36.189:6381 slave f6285c8a7506b224840d7b26b2b5d1671320c21f 0 1428817516066 5 connected b1a15a3cd14ea65671a7134850e17b8919a17da5 192.168.36.189:6380 myself,master - 0 0 4 connected 5461-10922 83fc65283bbbb71b4c089337df05594d67f4cab6 192.168.36.54:6382 slave b1a15a3cd14ea65671a7134850e17b8919a17da5 0 1428817515047 4 connected 26ce71d626175f88e0416e3f45b2bfb29304c7b3 192.168.36.54:6381 master - 0 1428817514946 2 connected 10923-16383 f6285c8a7506b224840d7b26b2b5d1671320c21f 192.168.36.54:6380 master - 0 1428817514844 1 connected 0-5460 de4302f43ff89843675446396552fd19f741246a 192.168.36.189:6382 slave 26ce71d626175f88e0416e3f45b2bfb29304c7b3 0 1428817516578 6 connected 參考文章:
1.Redis 官方集群教程
2.Redis 集群原理與使用
3.Redis 3.0.0集群試練
4.Redis3.0.0 集群示例