redis通常須要6個節點才能組成完整的高可用集羣,這裏咱們使用docker-compose
來快速搭建集羣。 集羣搭建通常分爲三個步驟:node
項目GitHub地址:github.com/willcat/red…git
因爲代碼更新,在配置文件中手動設置了容器名稱,因此文章和代碼中的容器名有區別,好比文章中的redis-cluster_redis-cluster-6380_1
,在代碼和實際運行中是node-80
,文章中的redis-cluster_redis-cluster-6381_1
,在代碼和實際運行中是node-81
github
進入redis-cluster-docker目錄,執行docker-compose up -d
redis
隨便進入一個容器好比redis-cluster_redis-cluster-6380_1
[1],docker exec -it redis-cluster_redis-cluster-6380_1 redis-cli -p 6380
,而後運行cluster nodes
命令,整個過程以下:docker
$ docker exec -it redis-cluster_redis-cluster-6380_1 redis-cli -p 6380
127.0.0.1:6380> cluster nodes
3914fe7597f9ad9e9c485cf473bcaa461973baaa :6380@16380 myself,master - 0 0 0 connected
複製代碼
能夠看到目前各個節點還只能返回本身的信息,每一個節點還不能感知到彼此。ruby
[1] 這是docker-compose
根據咱們在docker-compose.yml
配置的服務名稱自動生成的,若是不想使用默認名稱,能夠在配置文件中使用container_name
指定容器名稱 docker exec
bash
節點握手是指一批運行在集羣模式下的節點經過Gossip
協議彼此通訊,達到感知對方的過程。網絡
cluster meet {ip} {port}
命令,達到兩個節點間的握手,這兩個節點就組成了一個真正的彼此感知的集羣,以後兩個節點間會按期經過ping/pong
消息進行正常的節點通訊cluster meet {ip} {port}
命令,添加還沒有加入集羣的新節點127.0.0.1:6380> cluster nodes
c6db83c252a072407707917474001c70da649407 172.26.0.6:6385@16385 master - 0 1565199856348 3 connected
e356c336482f7a8a3f786674b96ac06030b0dcb4 172.26.0.3:6381@16381 master - 0 1565199855000 0 connected
dae83c485b9fb1357947944b36007c3371a750f2 172.26.0.7:6383@16383 master - 0 1565199857362 5 connected
c87aba899473356f25a919dc2d477340f5222ba4 172.26.0.2:6382@16382 master - 0 1565199855000 4 connected
5ebbd85dfbe1e4e01bae5f4954418a436453876c 172.26.0.5:6384@16384 master - 0 1565199855339 2 connected
3914fe7597f9ad9e9c485cf473bcaa461973baaa 172.26.0.4:6380@16380 myself,master - 0 1565199855000 1 connected
複製代碼
{app_name}_default
網絡中docker network ls
能夠查看網絡列表,docker network inspect <network_name>
能夠查看對應網絡的配置以及各個容器的ip。docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-cluster_redis-cluster-6385_1
命令直接查看某個容器的ip。節點創建握手以後,集羣還處於下線狀態,沒法執行寫操做。app
127.0.0.1:6380> set hello world
(error) CLUSTERDOWN Hash slot not served
複製代碼
查看集羣信息能夠看到集羣是fail
狀態工具
127.0.0.1:6380> 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:718
cluster_stats_messages_pong_sent:283
cluster_stats_messages_meet_sent:8
cluster_stats_messages_sent:1009
cluster_stats_messages_ping_received:283
cluster_stats_messages_pong_received:285
cluster_stats_messages_received:568
複製代碼
在各個節點上執行相似cluster addslots {0...5461}
的命令,將0~16383個slot平均分配到全部節點上。這裏咱們只分配三個節點,另外三個節點分別看成前面三個節點的從節點,從而在主節點出現故障時可以自動完成故障轉移。
//分配三個節點,注意,如下三個命令在登陸redis-cli以後是不成功的,只能使用redis-cli -p 6380 cluster addslots {0..5461}這種模式
$ docker exec -it redis-cluster_redis-cluster-6380_1 redis-cli -p 6380 cluster addslots {0..5461}
$ docker exec -it redis-cluster_redis-cluster-6381_1 redis-cli -p 6381 cluster addslots {5462..10922}
$ docker exec -it redis-cluster_redis-cluster-6382_1 redis-cli -p 6382 cluster addslots {10923..16282}
// 將三個未分配槽的節點設置爲從節點
127.0.0.1:6383> CLUSTER REPLICATE 3914fe7597f9ad9e9c485cf473bcaa461973baaa
OK
127.0.0.1:6384> CLUSTER REPLICATE e356c336482f7a8a3f786674b96ac06030b0dcb4
OK
127.0.0.1:6385> CLUSTER REPLICATE c87aba899473356f25a919dc2d477340f5222ba4
OK
複製代碼
這樣3主3從的集羣就搭建完成了,能夠感受到仍是比較麻煩的,因此redis官方在redis3.x
和redis4.x
提供了redis-trib.rb
工具方便咱們快速搭建集羣,在redis5.x
中更是能夠直接使用redis-cli
命令來直接完成集羣的一鍵搭建,省去了redis-trib.rb
依賴ruby環境的問題。在代碼中,readme.md裏提供了快速搭建的命令。
//官方指出: 能夠使用redis5.x 的redis-cli命令模式來搭建由redis-4.x組成的集羣。
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1
複製代碼
在集羣中某個節點讀寫不屬於此節點的數據會返回錯誤(error) MOVED 5798 172.20.0.6:6381
,爲了減小手動切換的環節,在開啓客戶端時能夠添加-c
參數,開啓請求重定向,詳細命令redis-cli -p 6380 -c
,這樣之後操做跨節點時會自動跳轉到相應的節點
大多數開發語言的Redis客戶端都採用Smart客戶端支持集羣協議,客戶端選擇能夠參考clients。
Moved
重定向負責協助Smart客戶端更新slot->node的映射關係。當集羣伸縮時,slot會發生遷移,這時去原來節點讀寫會返回(error) ASK {slot} {targetIP}:{targetPort}
錯誤,客戶端從ASK重定向異常提取出目標節點信息,發送asking
命令到目標節點打開客戶端鏈接標識,再執行鍵命令。若是存在則執行,不存在則返回不存在信息。
TODO