Redis Cluster採用虛擬槽分區,所有的key根據哈希函數映射到0~16383槽內,計算公式: slot = CRC16(key) & 16383 每個節點負責維護一部分槽以及槽所映射的鍵值對。 Redis虛擬槽分區的特點,解耦數據與節點之間的關係,簡化了節點擴容和收縮難度。但其存在如下限制 ...
Redis Cluster採用虛擬槽分區,所有的key根據哈希函數映射到0~16383槽內,計算公式:
slot = CRC16(key) & 16383
每個節點負責維護一部分槽以及槽所映射的鍵值對。
Redis虛擬槽分區的特點,解耦數據與節點之間的關係,簡化了節點擴容和收縮難度。但其存在如下限制:
1. key批量操作支持有限。只支持具有相同slot值的key執行批量操作。
2. 事務操作支持有限。只支持同一個節點上的多個key的事務操作。
3. key是數據分區的最小粒度,因為不能講一個大的鍵值對象,如hash,list等映射到不同的節點上。
4. 不支持多資料庫,單機下的Redis可以支持16個資料庫,但集群之只能使用一個資料庫空間,即db 0。
5. 複製結構只支持一層,從節點只能複製主節點,不支持嵌套樹狀複製結構。
如何手動創建一個Redis Cluster
創建三個目錄,分別用於存放數據,配置文件和日誌。
mkdir -p /opt/redis/data/
mkdir -p /opt/redis/conf/
mkdir -p /opt/redis/log
編輯配置文件
vim redis_6379.conf
port 6379 daemonize yes pidfile "/opt/redis/data/redis_6379.pid" loglevel notice logfile "/opt/redis/log/redis_6379.log" dbfilename "dump_6379.rdb" dir "/opt/redis/data" appendonly yes appendfilename "appendonly_6379.aof" cluster-enabled yes cluster-config-file /opt/redis/conf/nodes-6379.conf cluster-node-timeout 15000
為簡化起見,這裡只貼出了redis的幾個關鍵參數,其中,後面三個參數與Cluster有關。
cp redis_6379.conf redis_6380.conf
cp redis_6379.conf redis_6381.conf
cp redis_6379.conf redis_6382.conf
cp redis_6379.conf redis_6383.conf
cp redis_6379.conf redis_6384.conf
sed -i 's/6379/6380/g' redis_6380.conf sed -i 's/6379/6381/g' redis_6381.conf sed -i 's/6379/6382/g' redis_6382.conf sed -i 's/6379/6383/g' redis_6383.conf sed -i 's/6379/6384/g' redis_6384.conf
啟動所有節點
cd /opt/redis/conf redis-server redis_6379.conf redis-server redis_6380.conf redis-server redis_6381.conf redis-server redis_6382.conf redis-server redis_6383.conf redis-server redis_6384.conf
節點啟動後,會在conf目錄下創建nodes-xxxx.conf文件,文件中記錄了節點ID。
[root@slowtech conf]# ls nodes-6379.conf nodes-6381.conf nodes-6383.conf redis_6379.conf redis_6381.conf redis_6383.conf nodes-6380.conf nodes-6382.conf nodes-6384.conf redis_6380.conf redis_6382.conf redis_6384.conf [root@slowtech conf]# cat nodes-6379.conf 260a27a4afd7be954f7cb4fe12be10641f379746 :0@0 myself,master - 0 0 0 connected vars currentEpoch 0 lastVoteEpoch 0
將節點加入到集群中
redis-cli -p 6379 cluster meet 127.0.0.1 6380 redis-cli -p 6379 cluster meet 127.0.0.1 6381 redis-cli -p 6379 cluster meet 127.0.0.1 6382 redis-cli -p 6379 cluster meet 127.0.0.1 6383 redis-cli -p 6379 cluster meet 127.0.0.1 6384
cluster meet命令的流程,以第一條命令為例。
1. 6379節點在收到命令後,會為6380節點創建一個clusterNode結構,並將其添加到自己的clusterState.nodes字典里。接著,6379節點向6380節點發送一條MEET消息。
2. 6380節點在收到6379節點的meet消息後,也會為6379節點創建一個clusterNode結構,並將其添加到自己的clusterSta.nodes字典里。並向6379節點返回一條PONG消息。
3. 6379節點在收到這條PONG消息後,會向6380節點返回一個PING消息。
4 . 6380節點收到6379節點返回的PING消息,知道6379節點已經收到自己返回的PONG消息,握手完成。
之後,6379會將6380的消息通過Gossip協議傳播給集群中的其它節點,讓其它節點也同6380節點握手,最終,6380節點會被集群中的所有節點認識。
查看當前集群的節點信息
127.0.0.1:6379> cluster nodes 260a27a4afd7be954f7cb4fe12be10641f379746 127.0.0.1:6379@16379 myself,master - 0 1539088861000 1 connected 645438fcdb241603fbc92770ef08fa6d2d4c7ffc 127.0.0.1:6380@16380 master - 0 1539088860000 2 connected bf1aa1e626988a5a35bc2a837c3923d472e49a4c 127.0.0.1:6381@16381 master - 0 1539088860730 0 connected 5350673149500f4c2fd8b87a8ec1b01651572fae 127.0.0.1:6383@16383 master - 0 1539088861000 4 connected 7dd5f5cc8d96d08f35ff395d05eb30ac199f7568 127.0.0.1:6382@16382 master - 0 1539088862745 3 connected 8679f302610e9ea9a464c247f70924e34cd20512 127.0.0.1:6384@16384 master - 0 1539088862000 5 connected
雖然六個節點已經加入到集群中了,但此時集群仍處於下線狀態。
127.0.0.1:6379> cluster info cluster_state:fail cluster_slots_assigned:0 cluster_slots_ok:0 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:0 cluster_current_epoch:5 cluster_my_epoch:1 cluster_stats_messages_ping_sent:799 cluster_stats_messages_pong_sent:826 cluster_stats_messages_meet_sent:5 cluster_stats_messages_sent:1630 cluster_stats_messages_ping_received:826 cluster_stats_messages_pong_received:804 cluster_stats_messages_received:1630
分配槽
將16384個slot平均分配給6379,6380,6381三個節點。
redis-cli -p 6379 cluster addslots {0..5461}
redis-cli -p 6380 cluster addslots {5462..10922}
redis-cli -p 6381 cluster addslots {10923..16383}
集群的整個資料庫被分為16384個槽,集群中的每個節點可以處理0個或最多16384個槽。當資料庫中的16384個槽都有節點在處理時,集群處於上線狀態(ok),反之,如果資料庫中有任何一個槽沒有得到處理,則集群處理下線狀態(fail)。
查看集群狀態
# redis-cli -p 6379 127.0.0.1:6379> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:5 cluster_my_epoch:1 cluster_stats_messages_ping_sent:6212 cluster_stats_messages_pong_sent:6348 cluster_stats_messages_meet_sent:5 cluster_stats_messages_sent:12565 cluster_stats_messages_ping_received:6348 cluster_stats_messages_pong_received:6217 cluster_stats_messages_received:12565
查看節點和槽的分配關係
127.0.0.1:6379> cluster nodes 260a27a4afd7be954f7cb4fe12be10641f379746 127.0.0.1:6379@16379 myself,master - 0 1539094639000 1 connected 0-5461 645438fcdb241603fbc92770ef08fa6d2d4c7ffc 127.0.0.1:6380@16380 master - 0 1539094636362 2 connected 5462-10922 bf1aa1e626988a5a35bc2a837c3923d472e49a4c 127.0.0.1:6381@16381 master - 0 1539094639389 0 connected 10923-16383 5350673149500f4c2fd8b87a8ec1b01651572fae 127.0.0.1:6383@16383 master - 0 1539094637000 4 connected 7dd5f5cc8d96d08f35ff395d05eb30ac199f7568 127.0.0.1:6382@16382 master - 0 1539094638000 3 connected 8679f302610e9ea9a464c247f70924e34cd20512 127.0.0.1:6384@16384 master - 0 1539094638381 5 connected
使用cluster replicate添加從節點
cluster replicate命令必須在對應的從節點上執行,後面接的是主節點的節點ID。
[root@slowtech conf]# redis-cli -p 6382 127.0.0.1:6382> cluster replicate 260a27a4afd7be954f7cb4fe12be10641f379746 OK 127.0.0.1:6382> quit [root@slowtech conf]# redis-cli -p 6383 127.0.0.1:6383> cluster replicate 645438fcdb241603fbc92770ef08fa6d2d4c7ffc OK 127.0.0.1:6383> quit [root@slowtech conf]# redis-cli -p 6384 127.0.0.1:6384> cluster replicate bf1aa1e626988a5a35bc2a837c3923d472e49a4c OK
快捷命令
echo "cluster replicate `redis-cli -p 6379 cluster nodes | grep 6379 | awk '{print $1}'`" | redis-cli -p 6382 -x echo "cluster replicate `redis-cli -p 6379 cluster nodes | grep 6380 | awk '{print $1}'`" | redis-cli -p 6383 -x echo "cluster replicate `redis-cli -p 6379 cluster nodes | grep 6381 | awk '{print $1}'`" | redis-cli -p 6384 -x
查看節點和槽的分配關係
127.0.0.1:6384> cluster nodes 8679f302610e9ea9a464c247f70924e34cd20512 127.0.0.1:6384@16384 myself,slave bf1aa1e626988a5a35bc2a837c3923d472e49a4c 0 1539094947000 5 connected 7dd5f5cc8d96d08f35ff395d05eb30ac199f7568 127.0.0.1:6382@16382 slave 260a27a4afd7be954f7cb4fe12be10641f379746 0 1539094947000 3 connected 5350673149500f4c2fd8b87a8ec1b01651572fae 127.0.0.1:6383@16383 slave 645438fcdb241603fbc92770ef08fa6d2d4c7ffc 0 1539094946000 4 connected bf1aa1e626988a5a35bc2a837c3923d472e49a4c 127.0.0.1:6381@16381 master - 0 1539094948000 0 connected 10923-16383 645438fcdb241603fbc92770ef08fa6d2d4c7ffc 127.0.0.1:6380@16380 master - 0 1539094947306 2 connected 5462-10922 260a27a4afd7be954f7cb4fe12be10641f379746 127.0.0.1:6379@16379 master - 0 1539094948308 1 connected 0-5461
至此,我們基於Redis協議手動創建了一個Cluster,其由6個節點組成,3個主節點負責處理數據,3個從節點負責故障切換。
鍵到slot的映射演算法
HASH_SLOT=CRC16(key)mod16384
重新分片的流程
1. 對目標節點發送cluster setslot <slot> importing <source-node-id>命令,讓目標節點準備導入槽的數據。
2. 對源節點發送cluster setslot <slot> migrating <destination-node-id>命令,讓源節點準備遷出槽的數據。
3. 源節點迴圈執行cluster getkeysinslot {slot} {count}命令,獲取count個屬於槽{slot}的鍵。
4. 在源節點執行
4. 對於步驟3中獲取的每個key,redis-trib.rb都向源節點發送一個MIGRATE <target_ip> <target_port> <key_name> 0 <timeout> 命令,將被選中的鍵原子性地從源節點遷移至目標節點。
5. 重覆執行步驟3和4,直到源節點保存的所有屬於槽slot的鍵值對都被遷移到目標節點為止。
6. redis-trib.rb向集群中的任意一個節點發送CLUSTER SETSLOT <slot> NODE <node-id>命令,將槽slot指派給目標節點。這一消息會發送給整個集群。
客戶端ASK重定向流程
Redis集群支持線上遷移slot和數據來完成水平伸縮,當slot對應的數據從源節點到目標節點遷移過程中,客戶端需要做到智能識別,保證鍵命令可正常執行。例如,當一個slot數據從源節點遷移到目標節點時,可能會出現一部分數據在源節點,另一部分在目標節點。
如果出現這種情況,客戶端鍵執行流程將發生變化,如下所示,
1. 客戶端根據slot緩存發送命令到源節點,如果存在key則直接執行並返回結果。
2. 如果key不存在,則可能存在於目標節點,這時會回覆ASK重定向異常,格式如下:(error) ASK {slot} {targetIP}:{targetPort}。
3. 客戶單從ASK重定向異常提出目標節點信息,發送asking命令到目標節點打開客戶端連接標識,再執行鍵命令。如果存在則執行,不存在則返回不存在信息。
ASK與MOVED雖然都是對客戶端進的重定向,但是有著本質區別,前者說明集群正在進行slot數據遷移,所以只是臨時性的重定向,不會更新slot緩存,但是MOVED重定向說明鍵對應的槽已經明確指定到新的節點,會更新slot緩存。
模擬Redis Cluster FAILOVER的過程
模擬主節點故障,手動kill 6379節點。
1. 首先,該節點對應的從節點會有日誌輸出。
16387:S 15 Oct 10:34:30.149 # Connection with master lost. 16387:S 15 Oct 10:34:30.149 * Caching the disconnected master state. 16387:S 15 Oct 10:34:30.845 * Connecting to MASTER 127.0.0.1:6379 16387:S 15 Oct 10:34:30.845 * MASTER <-> SLAVE sync started 16387:S 15 Oct 10:34:30.845 # Error condition on socket for SYNC: Connection refused ... 16387:S 15 Oct 10:34:49.994 * MASTER <-> SLAVE sync started 16387:S 15 Oct 10:34:49.994 # Error condition on socket for SYNC: Connection refused 16387:S 15 Oct 10:34:50.898 * FAIL message received from bd341bb4c10e0dbff593bf7bafb1309842fba155 about 72af03587f5e9f064721d3b3a92b1439b3785623 16387:S 15 Oct 10:34:50.898 # Cluster state changed: fail
發現連接斷開的時間點是10:34:30.149,判斷其主觀下線的時間為10:34:50,相差20s,這也是cluster-node-timeout的設置。
2. 再來看看6380節點的日誌。
16383:M 15 Oct 10:34:50.897 * Marking node 72af03587f5e9f064721d3b3a92b1439b3785623 as failing (quorum reached). 16383:M 15 Oct 10:34:50.897 # Cluster state changed: fail
6381節點的日誌同樣如此,超過半數,因此標記6379節點為客觀下線。
3. 再來看看從節點的日誌
16387:S 15 Oct 10:34:51.003 * Connecting to MASTER 127.0.0.1:6379 16387:S 15 Oct 10:34:51.003 * MASTER <-> SLAVE sync started 16387:S 15 Oct 10:34:51.003 # Start of election delayed for 566 milliseconds (rank #0, offset 154). 16387:S 15 Oct 10:34:51.003 # Error condition on socket for SYNC: Connection refused
從節點識別正在複製的主節點進入客觀下線後準備選舉時間,日誌列印了選舉延遲566毫秒之後執行。
延遲選舉時間到達後,從節點更新配置紀元併發起故障選舉。
16387:S 15 Oct 10:34:51.605 # Starting a failover election for epoch 7.
4. 6380和6381主節點為從節點投票
16385:M 15 Oct 10:34:51.618 # Failover auth granted to 886c1f990191854df1972c4bc4d928e44bd36937 for epoch 7
5. 從節點獲取2個主節點投票之後,超過半數執行替換主節點操作,完成故障切換。
16387:S 15 Oct 10:34:51.622 # Failover election won: I'm the new master. 16387:S 15 Oct 10:34:51.622 # configEpoch set to 7 after successful failover 16387:M 15 Oct 10:34:51.622 # Setting secondary replication ID to 207c65316707a8ec2ca83725ae53ab49fa25dbfb, valid up to offset: 155. New replication ID is 0ec4aac9562b3f4165244153646d9c9006953736
16387:M 15 Oct 10:34:51.622 * Discarding previously cached master state. 16387:M 15 Oct 10:34:51.622 # Cluster state changed: ok
Failover的流程
一、主觀下線
集群中每個節點都會定期向其他節點發送ping消息,接收節點回覆pong消息作為響應。如果在cluster-node-timeout時間內通信一直失敗,則發送節點會認為接收節點存在故障,把接收節點標記為主觀下線(pfail)狀態。
二、客觀下線
當某個節點判斷另一個節點主觀下線後,相應的節點狀態會跟隨消息在集群內傳播。通過Gossip消息傳播,集群內節點不斷收集到故障節點的下線報告。當半數以上持有槽的主節點都標記某個節點是主觀下線時,觸發客觀下線流程。
集群中的節點每次接收到其他節點的pfail狀態,都會嘗試觸發客觀下線,流程說明:
1. 首先統計有效的下線報告數量,如果小於集群內持有槽的主節點總數的一半則退出。
2. 當下線報告大於槽主節點數量一半時,標記對應故障節點為客觀下線狀態。
3. 向集群廣播一條fail消息,通知所有的節點將故障節點標記為客觀下線,fail消息的消息體只包含故障節點的ID。
廣播fail消息是客觀下線的最後一步,它承擔著非常重要的職責:
1. 通知集群內所有的節點標記故障節點為客觀下線狀態並立刻生效。
2. 通知故障節點的從節點觸發故障轉移流程。
三、故障切換
故障節點變為客觀下線後,如果下線節點是持有槽的主節點則需要在它的從節點中選出一個替換它,從而保證集群的高可用。下線主節點的所有從節點承擔故障恢復的義務,當從節點通過內部定時任務發現自身複製的主節點進入客觀下線時,將會觸發故障切換流程。
1.資格檢查
每個從節點都要檢查最後與主節點斷線時間,判斷是否有資格替換故障的主節點。如果從節點與主節點斷線時間超過cluster-node-time*cluster-slave-validity-factor,則當前從節點不具備故障轉移資格。參數cluster-slavevalidity-factor用於從節點的有效因數,預設為10。
2.準備選舉時間
當從節點符合故障切換資格後,更新觸發切換選舉的時間,只有到達該時間後才能執行後續流程。
這裡之所以採用延遲觸發機制,主要是通過對多個從節點使用不同的延遲選舉時間來支持優先順序問題。複製偏移量越大說明從節點延遲越低,那麼它應該具有更高的優先順序來替換故障主節點。
3.發起選舉
當從節點定時任務檢測到達故障選舉時間(failover_auth_time)到達後,發起選舉流程如下:
1> 更新配置紀元
2> 廣播選舉消息
在集群內廣播選舉消息(FAILOVER_AUTH_REQUEST),並記錄已發送過消息的狀態,保證該從節點在一個配置紀元內只能發起一次選舉。
4.選舉投票
只有持有槽的主節點才會處理故障選舉消息(FAILOVER_AUTH_REQUEST),因為每個持有槽的節點在一個配置紀元內都有唯一的一張選票,當接到第一個請求投票的從節點消息時回覆FAILOVER_AUTH_ACK消息作為投票,之後相同配置紀元內其他從節點的選舉消息將忽略。
Redis集群沒有直接使用從節點進行領導者選舉,主要因為從節點數必須大於等於3個才能保證湊夠N/2+1個節點,將導致從節點資源浪費。使用集群內所有持有槽的主節點進行領導者選舉,即使只有一個從節點也可以完成選舉過程。
5.替換主節點
當從節點收集到足夠的選票之後,觸發替換主節點操作:
1> 當前從節點取消複製變為主節點。
2> 執行clusterDelSlot操作撤銷故障主節點負責的槽,並執行clusterAddSlot把這些槽委派給自己。
3> 向集群廣播自己的pong消息,通知集群內所有的節點當前從節點變為主節點並接管了故障主節點的槽信息。
故障切換時間
在介紹完故障發現和恢復的流程後,我們估算下故障切換時間:
1> 主觀下線(pfail)識別時間=cluster-node-timeout。
2> 主觀下線狀態消息傳播時間<=cluster-node-timeout/2。消息通信機制對超過cluster-node-timeout/2未通信節點會發起ping消息,消息體在選擇包含哪些節點時會優先選取下線狀態節點,所以通常這段時間內能夠收集到半數以上主節點的pfail報告從而完成故障發現。
3> 從節點轉移時間<=1000毫秒。由於存在延遲發起選舉機制,偏移量最大的從節點會最多延遲1秒發起選舉。通常第一次選舉就會成功,所以從節點執行轉移時間在1秒以內。
根據以上分析可以預估出故障轉移時間,如下:
failover-time(毫秒) ≤ cluster-node-timeout + cluster-node-timeout/2 + 1000
因此,故障轉移時間跟cluster-node-timeout參數息息相關,預設15秒。
Redis Cluster的相關參數
cluster-enabled <yes/no>:是否開啟集群模式。
cluster-config-file <filename>:集群配置文件,由集群自動維護,不建議手動編輯。
cluster-node-timeout <milliseconds>:集群中每個節點都會定期向其他節點發送ping消息,接收節點回覆pong消息作為響應。如果在cluster-node-timeout時間內通信一直失敗,則發送節點會認為接收節點存在故障,把接收節點標記為主觀下線(pfail)狀態。預設15000,即15s。
cluster-slave-validity-factor <factor>:每個從節點都要檢查最後與主節點斷線時間,判斷其是否有資格替換故障的主節點。如果從節點與主節點斷線時間超過cluster-node-time*cluster-slave-validity-factor,則當前從節點不具備故障轉移資格。
cluster-migration-barrier <count>:主節點需要的最小從節點數,只有達到這個數,才會將多餘的從節點遷移給其它孤立的主節點使用。
cluster-require-full-coverage <yes/no>:預設情況下當集群中16384個槽,有任何一個沒有指派到節點時,整個集群是不可用的。對應線上上,如果某個主節點宕機,而又沒有從節點的話,是不允許對外提供服務的。建議將該參數設置為no,避免某個主節點的故障導致其它主節點不可用。
Redis Cluster的相關命令
CLUSTER ADDSLOTS slot [slot ...]:對當前節點手動分配slot。
CLUSTER MEET ip port:將其它節點添加到Redis Cluster中。
CLUSTER INFO:列印Cluster的相關信息。
# redis-cli -c cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:702 cluster_stats_messages_pong_sent:664 cluster_stats_messages_sent:1366 cluster_stats_messages_ping_received:659 cluster_stats_messages_pong_received:702 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:1366
CLUSTER KEYSLOT key:查看key對應的slot
127.0.0.1:6379> cluster keyslot hello (integer) 866 127.0.0.1:6379> cluster keyslot world (integer) 9059 127.0.0.1:6379> cluster keyslot hello{tag} (integer) 8338 127.0.0.1:6379> cluster keyslot world{tag} (integer) 8338
CLUSTER NODES:獲取Cluster的節點信息,與當前節點的集群配置文件中的內容基本一致,只不過後者還會維護當前節點的配置紀元。
[root@slowtech conf]# redis-cli -p 6380 -c cluster nodes 72969ae6214dce5783d5b13b1bad34701303e96c 127.0.0.1:6382@16382 slave 7396e133fd8143335d5991734e68fcfcfc5adfd1 0 1539594959692 4 connected a0efce44c96f95b2cdaf1101805710f41dfe4d06 127.0.0.1:6381@16381 master - 0 1539594962724 3 connected 10923-16383 276cf1128c50faa81a6b073079cc5e2c7a51a4ec 127.0.0.1:6380@16380 myself,master - 0 1539594958000 2 connected 5461-10922 b39826ebe9e741c8dc1fea7ee6966a42c5030726 127.0.0.1:6384@16384 slave a0efce44c96f95b2cdaf1101805710f41dfe4d06 0 1539594961000 6 connected 81f99ce264626895e30a5030ac27b84efedfa622 127.0.0.1:6383@16383 slave 276cf1128c50faa81a6b073079cc5e2c7a51a4ec 0 1539594961713 5 connected 7396e133fd8143335d5991734e68fcfcfc5adfd1 127.0.0.1:6379@16379 master - 0 1539594960703 1 connected 0-5460 [root@slowtech conf]# cat nodes-6380.conf 72969ae6214dce5783d5b13b1bad34701303e96c 127.0.0.1:6382@16382 slave 7396e133fd8143335d5991734e68fcfcfc5adfd1 0 1539592972569 4 connected a0efce44c96f95b2cdaf1101805710f41dfe4d06 127.0.0.1:6381@16381 master - 0 1539592969000 3 connected 10923-16383 276cf1128c50faa81a6b073079cc5e2c7a51a4ec 127.0.0.1:6380@16380 myself,master - 0 1539592969000 2 connected 5461-10922 b39826ebe9e741c8dc1fea7ee6966a42c5030726 127.0.0.1:6384@16384 slave a0efce44c96f95b2cdaf1101805710f41dfe4d06 0 1539592971000 6 connected 81f99ce264626895e30a5030ac27b84efedfa622 127.0.0.1:6383@16383 slave 276cf1128c50faa81a6b073079cc5e2c7a51a4ec 0 1539592971000 5 connected 7396e133fd8143335d5991734e68fcfcfc5adfd1 127.0.0.1:6379@16379 master - 0 1539592971558 1 connected 0-5460 vars currentEpoch 6 lastVoteEpoch 0
CLUSTER REPLICATE node-id:在對應的從節點上執行,後面接的是主節點的節點ID。
CLUSTER SLAVES node-id:查看某個節點的從節點。
[root@slowtech conf]# redis-cli -c cluster slaves a0efce44c96f95b2cdaf1101805710f41dfe4d06 1) "b39826ebe9e741c8dc1fea7ee6966a42c5030726 127.0.0.1:6384@16384 slave a0efce44c96f95b2cdaf1101805710f41dfe4d06 0 1539596409000 6 connected" [root@slowtech conf]# redis-cli -c cluster slaves b39826ebe9e741c8dc1fea7ee6966a42c5030726 (error) ERR The specified node is not a master
CLUSTER SLOTS:輸出slot與節點的映射關係。
# redis-cli cluster slots 1) 1) (integer) 5461 2) (integer) 10922 3) 1) "127.0.0.1" 2) (integer) 6380 3) "276cf1128c50faa81a6b073079cc5e2c7a51a4ec" 4) 1) "127.0.0.1" 2) (integer) 6383 3) "81f99ce264626895e30a5030ac27b84efedfa622" 2) 1) (integer) 0 2) (integer) 5460 3) 1) "127.0.0.1" 2) (integer) 6379 3) "7396e133fd8143335d5991734e68fcfcfc5adfd1" 4) 1) "127.0.0.1" 2) (integer) 6382 3) "72969ae6214dce5783d5b13b1bad34701303e96c" 3) 1) (integer) 10923 2) (integer) 16383 3) 1) "127.0.0.1" 2) (integer) 6381 3) "a0efce44c96f95b2cdaf1101805710f41dfe4d06" 4) 1) "127.0.0.1" 2) (integer) 6384 3) "b39826ebe9e741c8dc1fea7ee6966a42c5030726"
READONLY:預設情況下,從節點不對外提供讀服務,即使收到了讀請求,也會重定向到對應的主節點。若要讀節點對外提供讀服務,可執行readonly。
# redis-cli -p 6382 127.0.0.1:6382> get k3 (error) MOVED 4576 127.0.0.1:6379 127.0.0.1:6382> readonly OK 127.0.0.1:6382> get k3 "hello"
READWRITE: 關閉READONLY選項。
# redis-cli -p 6382 127.0.0.1:6382> get k3 (error) MOVED 4576 127.0.0.1:6379 127.0.0.1:6382> readonly OK 127.0.0.1:6382> get k3 "hello" 127.0.0.1:6382> readwrite OK 127.0.0.1:6382> get k3 (error) MOVED 4576 127.0.0.1:6379
CLUSTER SETSLOT slot IMPORTING|MIGRATING|STABLE|NODE [node-id]:設置slot的狀態。
CLUSTER DELSLOTS slot [slot ...]:
註意:
1. 是否開啟集群模式,從進程名中也可看出。
[root@slowtech conf]# ps -ef | grep redis root 17497 1 0 20:18 ? 00:00:00 redis-server 127.0.0.1:6379 [cluster] root 17720 1 0 20:21 ? 00:00:00 redis-server 127.0.0.1:6380 [cluster] root 17727 1 0 20:21 ? 00:00:00 redis-server 127.0.0.1:6381 [cluster] root 17734 1 0 20:21 ? 00:00:00 redis-server 127.0.0.1:6382 [cluster] root 17741 1 0 20:21 ? 00:00:00 redis-server 127.0.0.1:6383 [cluster] root 17748 1 0 20:21 ? 00:00:00 redis-server 127.0.0.1:6384 [cluster] root 18154 15726 0 20:29 pts/5 00:00:00 grep --color=auto redis