redis 集羣某些功能須要依賴 ruby 運行環境,基於yum進行安裝:node
$ yum install ruby*
安裝redis的ruby組件:redis
$ gem install redis
提示:shell
[root@bogon redis]# gem install redis ERROR: Could not find a valid gem 'redis' (>= 0), here is why: Unable to download data from https://rubygems.org/ - Errno::ECONNRESET: Connection reset by peer - SSL_connect (https://rubygems.org/latest_specs.4.8.gz)
解決辦法ruby
$ sudo gem sources -r https://rubygems.org $ sudo gem sources -a http://rubygems.org
重試,發現能夠安裝成功,以前的 ERROR 變成了 WARNINGbash
本次實驗採用4個節點來搭建 redis cluster,其中 16379, 16479, 16579 爲集羣的3個主節點,承擔整個集羣的槽位分配,16379 和 16380 爲主從結構服務器
192.168.1.160 16379 (master) <--> 192.168.1.160 16380 (slave)測試
192.168.1.160 16479spa
192.168.1.160 165793d
redis 集羣安裝很是簡單,只須要下載 redis 3.x+ 版本,而且修改下配置文件,打開集羣配置便可日誌
重啓 redis 服務
$ ./src/redis-server config/redis_16379.conf $ ./src/redis-server config/redis_16380.conf $ ./src/redis-server config/redis_16479.conf $ ./src/redis-server config/redis_16579.conf
鏈接上16379
./src/redis-cli -p 16379
將 16479 和 16579 加入集羣中
> cluster meet 192.168.1.160 16479 > cluster meet 192.168.1.160 16579
cluster_state:fail # 此時整個集羣仍是 fail 狀態,還須要爲每一個節點分片槽位,redis cluster 總共 16384 [0, 16383] 個槽位,只有將每一個槽位都分配到具體的節點,整個集羣纔會爲可用狀態
cluster_known_nodes:3 # 說明集羣中已經有三個節點
cluster_size:0 # 說明集羣中尚未節點承擔槽位分配
槽位分配的命令,以下指令將第0個槽位分配給 16379 redis 服務
$ ./src/redis-cli -h 127.0.0.1 -p 16379 cluster addslots 0
這裏爲了簡單處理,直接經過一個 shell 腳本將 16384 個槽位均分給3個節點,具體 shell 腳本以下
#!/bin/bash all_ports=(16379 16479 16579) for i in {0..16383}; do val=`expr $i % 3` /usr/local/redis/src/redis-cli -h 127.0.0.1 -p ${all_ports[$val]} cluster addslots $i; done
完成以後,查看集羣的狀態
cluster_state:ok # 此時集羣爲可用狀態
另外可使用 redis-trib.rb 腳本快速分配槽位,方法以下
./src/redis-trib.rb create 192.168.1.160:16379 192.168.1.160:16479 192.168.1.160:16579
注意:
1)redis 服務啓動以後不須要執行 cluster meet 命令,不然提示錯誤
2)這裏不能使用 create 127.0.0.1:16379 127.0.0.1:16479 這種 127 的地址,由於若是集羣之間通信的IP是127的地址,那麼當使用 jedis 這類客戶端操做 cluster 時,獲取到的集羣節點IP也會是127的地址,那麼出現重定向請求時將出現錯誤
截圖能夠看出 0-5460 槽位分配給了 16379;5461-10922 槽位分配給了 16479 ...
結束以後查看集羣狀態(cluster info)看到整個集羣的狀態爲:ok
> redis-cli -h 192.168.1.160 -p 16379 –c (注意:這裏的 –c 參數,表示採用集羣方式鏈接)
此時看到這裏能夠正常地將其餘節點的請求轉發出去
先給 16379 添加一臺從服務器 16380
$ ./redis-trib.rb add-node --slave --master-id 9c4395ebb3142a3e03d0c6892d5f17f2eac20e7d 192.168.1.160:16380 192.168.1.160:16379
其中 9c4395ebb3142a3e03d0c6892d5f17f2eac20e7d 爲 16379 (master) 的 node id (集羣中各個節點的 node id 能夠經過 cluster nodes 命令查看到)
$ ./redis-trib.rb info 192.168.1.160:16379
16379 有一個 slave,中止 16379 的服務,查看16380的日誌,驗證主從切換的過程
16380 的日誌中輸出能夠看到,當16379宕機後,16380發起了一個新的選舉,而且由於這個主從結構中只有一個從,因此本身被選舉成了新的主,而後整個集羣的狀態變成了ok
從新啓動 16379 的服務,驗證 16379 會成爲 16380 的從節點,查看 16379 啓動日誌,發現 16379 會自動切換爲從 Reconfiguring myself as a replica of 591a0241a417bad43afa9fc84b6c6b3958dc11a6
4251:M 02 May 18:58:30.595 * The server is now ready to accept connections on port 16379 4251:M 02 May 18:58:30.616 # Configuration change detected. Reconfiguring myself as a replica of 591a0241a417bad43afa9fc84b6c6b3958dc11a6 4251:S 02 May 18:58:30.616 # Cluster state changed: ok 4251:S 02 May 18:58:31.625 * Connecting to MASTER 192.168.1.160:16380
先經過 cluster nodes 命令查看出集羣中全部節點的 node id,以下
M: 5e2946da32a6d0b03f3805415fade827ef50561e 192.168.1.160:16379
M: 5aa58505ead83ab8e2ea46941377130d2cbdbc6e 192.168.1.160:16479
M: 41c251b110ce1bd2da908f9ef35460fc4621e138 127.0.0.1:16579
經過下面的命令生成遷移計劃,而後根據提示輸入相關信息,便可完成遷移
$ ./src/redis-trib.rb reshard 127.0.0.1:16579
How many slots do you want to move (from 1 to 16384) 2731 //輸入被遷移的slot的數量(由於這裏須要將16579全部的 slot 遷出,因此這裏輸入16579節點的總slot數量)
What is the receiving node ID? //輸入目的地節點的id,執行第一行命的時候會打印出全部的節點信息
Please enter all the source node IDs. //輸入被遷移的槽所在的節點,指定多個,入done確認入完,即將這些slot遷入到那個節點,這裏遷移到了16379節點
Do you want to proceed with the proposed reshard plan (yes/no)? Yes //遷移計劃確認
確認計劃以後,等待計劃執行完成便可
# ./redis-trib.rb del-node 127.0.0.1:16380 591a0241a417bad43afa9fc84b6c6b3958dc11a6
提示該節點還有槽位分配,必需要將數據 rehash 後才能刪除,這裏爲了測試直接將全部槽位移除
[root@bogon src]# ./redis-cli -h 127.0.0.1 -p 16380 -c 127.0.0.1:16380> CLUSTER flushslots OK [root@bogon src]# ./redis-trib.rb del-node 127.0.0.1:16380 591a0241a417bad43afa9fc84b6c6b3958dc11a6 >>> Removing node 591a0241a417bad43afa9fc84b6c6b3958dc11a6 from cluster 127.0.0.1:16380 >>> Sending CLUSTER FORGET messages to the cluster... >>> 192.168.1.160:16379 as replica of 192.168.1.160:16579 >>> SHUTDOWN the node.
再次嘗試刪除16380節點,刪除成功
CLUSTER INFO 打印集羣的信息
CLUSTER NODES 列出集羣當前已知的全部節點(node),以及這些節點的相關信息。
CLUSTER MEET <ip> <port> 將 ip 和 port 所指定的節點添加到集羣當中,讓它成爲集羣的一份子。
CLUSTER FORGET <node_id> 從集羣中移除 node_id 指定的節點。
CLUSTER REPLICATE <node_id> 將當前節點設置爲 node_id 指定的節點的從節點
CLUSTER SAVECONFIG 將節點的配置文件保存到硬盤裏面。
CLUSTER ADDSLOTS <slot> [slot ...] 將一個或多個槽(slot)指派(assign)給當前節點。
CLUSTER DELSLOTS <slot> [slot ...] 移除一個或多個槽對當前節點的指派。
CLUSTER FLUSHSLOTS 移除指派給當前節點的全部槽,讓當前節點變成一個沒有指派任何槽的節點。
CLUSTER SETSLOT <slot> NODE <node_id> 將槽 slot 指派給 node_id 指定的節點,若是槽已經指派給另外一個節點,那麼先讓另外一個節點刪除該槽>,而後再進行指派。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 將本節點的槽 slot 遷移到 node_id 指定的節點中。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 從 node_id 指定的節點中導入槽 slot 到本節點。
CLUSTER SETSLOT <slot> STABLE 取消對槽 slot 的導入(import)或者遷移(migrate)。
CLUSTER KEYSLOT <key> 計算鍵 key 應該被放置在哪一個槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的鍵值對數量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 個 slot 槽中的鍵。