redis 集群

集群

1.Redis 集群的優(yōu)勢

自動分割數(shù)據(jù)到不同的節(jié)點上抛丽。
整個集群的部分節(jié)點失敗或者不可達的情況下能夠繼續(xù)處理命令失暂。

特點

主從復制

實現(xiàn)了高可用

數(shù)據(jù)分片存儲

集群節(jié)點的 meet 過程

image
image

指派槽

image

客戶端和槽

image

3. Redis 集群的安裝

原生命令安裝

步驟

  1. 配置開啟集群節(jié)點

  2. 配置 meet

  3. 指派槽

  4. 配置主從

實例操作

準備兩臺虛擬機:
一臺啟動三個 Redis 實例作為 主節(jié)點
另一臺啟動三個 Redis 實例作為 從節(jié)點

架構圖
image

一、在一臺服務器上手動部署 redis 集群

在一臺服務器上啟動六個 Redis 實例淋袖,三臺作為主節(jié)點凭迹,三臺作為從節(jié)點

實驗步驟
  1. 先編輯一個集群的配置文件

編譯配置文件 /etc/redis/7001.conf, 添加如下內(nèi)容:

bind 0.0.0.0
port 7001
daemonize yes

# 允許任何地址不使用密碼訪問我
protected-mode yes
dir "/redis/data/"
logfile  "cluster-7001.log"
dbfilename "cluster-dump-7001.log"
cluster-enabled yes
cluster-config-file cluster-redis-7001.conf

# 不需要集群的全部節(jié)點完好才提供服務
cluster-require-full-coverage no
  1. 再創(chuàng)建其他集群的配置文件

    image
sed 's/7001/7002/g' 7001.conf > 7002.conf
sed 's/7001/7003/g' 7001.conf > 7003.conf
sed 's/7001/7004/g' 7001.conf > 7011.conf
sed 's/7001/7005/g' 7001.conf > 7012.conf
sed 's/7001/7006/g' 7001.conf > 7013.conf

3.啟動 redis 進程

mkdir -p /redis/data
redis-server /etc/redis/7001.conf 
redis-server /etc/redis/7002.conf 
redis-server /etc/redis/7003.conf 
redis-server /etc/redis/7011.conf 
redis-server /etc/redis/7012.conf
redis-server /etc/redis/7013.conf 

4.檢查進程

ps  aux| grep  redis-server
image.png

假設你現(xiàn)在去連接到任意一個節(jié)點上執(zhí)行操作會返回集群目前是沒有啟動的信息。

原因是目前集群各節(jié)點之間沒有進行 meet 操作鸡捐,都是各自孤立的狀態(tài)。

image

可以使用如下命令查看集群的相關信息

image

還可以查看某一個集群節(jié)點信息麻裁,第一列是集群節(jié)點 ID

image
  1. 集群節(jié)點之間的 meet
    我們下面使用主節(jié)點 127.0.0.1:7001 去依次的 meet 其他 5 個節(jié)點箍镜。
redis-cli -p 7001 cluster meet 127.0.0.1 7002
redis-cli -p 7001 cluster meet 127.0.0.1 7003
redis-cli -p 7001 cluster meet 127.0.0.1 7004
redis-cli -p 7001 cluster meet 127.0.0.1 7005
redis-cli -p 7001 cluster meet 127.0.0.1 7006
image

查看集群信息和節(jié)點 信息


image

image
  1. 給集群節(jié)點分配 數(shù)據(jù)槽
    集群的槽號是 從 0 開始,到 16383 結束煎源,共 16384 個色迂。

槽的分配是拿 16384 除以集群中主節(jié)點的個數(shù),得到每個主節(jié)點應該被分配給槽的數(shù)量薪夕。

所以現(xiàn)在的計劃是:

image

命令

redis-cli  -h 被添加的主機 IP -p 端口 cluster  addslots  槽號

假如給 7001 分配 0 號槽脚草。命令應該是:

redis-cli  -h 172.16.153.178  -p 7001 cluster  addslots  0

每次只能分配一個 槽號赫悄,所以我們可以寫個腳本原献,當然這種方式是不會在生產(chǎn)環(huán)境中使用的馏慨,這里只是為了理解集群的架構關系。

腳本

#!/bin/sh

target_host_ip=$1
target_host_port=$2

star=$3
end=$4

for slot in $(seq ${star} ${end})
do
    echo "正在給 ${target_host_ip} ${target_host_port} 添加${slot}"
    redis-cli -h ${target_host_ip} -p ${target_host_port}  cluster addslots ${slot}

done

使用腳本

sh mutil-addslots.sh 172.16.153.178 7002 5462 10922
sh mutil-addslots.sh 172.16.153.178 7003 10923 16383

多線程版

target_host_ip=$1
target_host_port=$2

star=$3
end=$4

num=$5

mkfifo t  # 創(chuàng)建命名管道文件
exec 7<>t   # 給命名管道起個文件描述符
rm -rf t   # 刪除這個命名管道文件姑隅,但是管道依然存在写隶,可以使用文件描述符 7 進行使用。

for  i in $(seq 1 ${num})  # 向這個管道中輸入相應數(shù)據(jù)的空行
do
    echo >&7  # 每一行就是一次并發(fā)
done

for slot in $(seq ${star} ${end})
do
    read -u7 # 這個不能變

    {
        echo " 主機 ${target_host_ip} 端口 ${target_host_port} 數(shù)據(jù)槽 ${slot}"
        redis-cli -h ${target_host_ip} -p ${target_host_port} \
        cluster addslots  ${slot}
        echo >&7

    }&
done

wait  # 這個不能變讲仰, 就是等待上面的所有后臺進程結束
exec 7>&-  # 這個不能變慕趴,
echo "任務執(zhí)行完畢"

最后查看集群信息

image

可以發(fā)現(xiàn)此時集群的狀態(tài)是 OK 的。

查看節(jié)點信息

image
  1. 給集群節(jié)點配置主從關系

命令語法

redis-cli   -p  從節(jié)點端口   cluster  replicate  主節(jié)點的 ID

實操

切換到從節(jié)點所在的主機鄙陡,這樣有便于操作

先獲取到集群各個節(jié)點的 ID

image

再按照計劃好的進行復制關系的設置

[root@s2 ~]# redis-cli -p 7011 cluster replicate 587b37f1bbe86dcce2b21e3890a61e9b5cdabade
OK
[root@s2 ~]# redis-cli -p 7012 cluster replicate 9d2617ed1892ad08d0bc66b50dada6d53901cce3
OK
[root@s2 ~]# redis-cli -p 7013 cluster replicate e3f9b763619c0f94ce943e57766001f0283f6c51
OK

查看集群節(jié)點信息冕房,驗證主從關系

redis-cli   -p  7011 cluster  nodes
image

完全配置好后,可以觀察集群的數(shù)據(jù)槽的分配情況

redis-cli -p 7011 cluster  slots

最后用客戶端登錄集群的方式登錄到集群中的任意一個節(jié)點趁矾,設置鍵值對進行測試耙册。

image

二、使用官方工具 redis-trib.rb 進行部署

官方工具依賴于 Ruby

1. 下載毫捣、編譯详拙、安裝 Ruby

點我到下載頁面

wget https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.1.tar.gz

安裝依賴包

yum  install  zlib-devel readline openssl-devel gcc  gcc-c++

點我查看具體安裝方法

tar xf ruby-2.6.1.tar.gz
cd ruby-2.6.1
./configure
make && make install

2. 安裝 rubygem redis

一個 ruby 語言實現(xiàn)的訪問 Redis 集群的客戶端

點我到官網(wǎng)下載地址

cd ..
 wget https://rubygems.org/rubygems/rubygems-3.0.2.tgz
 tar -xf rubygems-3.0.2.tgz
cd rubygems-3.0.2/
ruby setup.rb
gem install redis

3. 安裝 redis-trib.rb

redis-trib 位于 Redis 源碼的 src 文件夾中, 它是一個 Ruby 程序蔓同, 這個程序通過向實例發(fā)送特殊命令來完成創(chuàng)建新集群饶辙, 檢查集群, 或者對集群進行重新分片(reshared)等工作斑粱。

cp   ~/redis-4.0.10/src/redis-trib.rb   /usr/local/bin/
chmod +x redis-trib.rb

沒有源碼安裝的可以從以下網(wǎng)址獲取
Redis 源碼 src 中的 redis-trib.rb 文件內(nèi)容

create:創(chuàng)建集群

check:檢查集群

info:查看集群信息

fix:修復集群

reshard:在線遷移slot

rebalance:平衡集群節(jié)點slot數(shù)量

add-node:添加新節(jié)點

del-node:刪除節(jié)點

set-timeout:設置節(jié)點的超時時間

call:在集群所有節(jié)點上執(zhí)行命令

import:將外部redis數(shù)據(jù)導入集群

配置集群

假如你完全安裝這個文檔做的實驗的換弃揽,此時配置集群之前,需要把之前的集群進程都停掉则北。

先在從節(jié)點上執(zhí)行蹋宦,再到主節(jié)點上執(zhí)行

ps -ef | grep redis-server | grep -v 'grep' | awk '{print $2}' |xargs  kill

接著分別在兩臺主機上,把之前集群產(chǎn)生的數(shù)據(jù)清除

rm -rf /redis/data/*

再重新啟動這些節(jié)點的服務進程

redis-server 7001.conf 
redis-server 7002.conf 
redis-server 7003.conf 
redis-server 7011.conf 
redis-server 7012.conf
redis-server 7013.conf 
image.png

之后使用如下命令創(chuàng)建集群

redis-trib.rb  create  --replicas  1  主節(jié)點1的IP:端口    主節(jié)點2的IP:端口    主節(jié)點3的IP:端口   從節(jié)點1的IP:端口    從節(jié)點2的IP:端口    從節(jié)點3的IP:端口  

選項–replicas 1 表示我們希望為集群中的每個主節(jié)點創(chuàng)建一個從節(jié)點咒锻。

redis-trib.rb create --replicas 1  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 127.0.0.1:7006
image
image
image

創(chuàng)建流程如下:
1冷冗、首先為每個節(jié)點創(chuàng)建ClusterNode對象,包括連接每個節(jié)點惑艇。檢查每個節(jié)點是否為獨立且db為空的節(jié)點蒿辙。執(zhí)行l(wèi)oad_info方法導入節(jié)點信息。
2滨巴、檢查傳入的master節(jié)點數(shù)量是否大于等于3個思灌。只有大于3個節(jié)點才能組成集群。
3恭取、計算每個master需要分配的slot數(shù)量泰偿,以及給master分配slave。分配的算法大致如下:
先把節(jié)點按照host分類蜈垮,這樣保證master節(jié)點能分配到更多的主機中耗跛。
不停遍歷遍歷host列表裕照,從每個host列表中彈出一個節(jié)點,放入interleaved數(shù)組调塌。直到所有的節(jié)點都彈出為止晋南。
master節(jié)點列表就是interleaved前面的master數(shù)量的節(jié)點列表。保存在masters數(shù)組羔砾。
計算每個master節(jié)點負責的slot數(shù)量负间,保存在slots_per_node對象,用slot總數(shù)除以master數(shù)量取整即可姜凄。
遍歷masters數(shù)組政溃,每個master分配slots_per_node個slot,最后一個master态秧,分配到16384個slot為止玩祟。
接下來為master分配slave,分配算法會盡量保證master和slave節(jié)點不在同一臺主機上屿聋。對于分配完指定slave數(shù)量的節(jié)點空扎,還有多余的節(jié)點,也會為這些節(jié)點尋找master润讥。分配算法會遍歷兩次masters數(shù)組转锈。
第一次遍歷masters數(shù)組,在余下的節(jié)點列表找到replicas數(shù)量個slave楚殿。每個slave為第一個和master節(jié)點host不一樣的節(jié)點撮慨,如果沒有不一樣的節(jié)點,則直接取出余下列表的第一個節(jié)點脆粥。
第二次遍歷是在對于節(jié)點數(shù)除以replicas不為整數(shù)砌溺,則會多余一部分節(jié)點。遍歷的方式跟第一次一樣变隔,只是第一次會一次性給master分配replicas數(shù)量個slave规伐,而第二次遍歷只分配一個,直到余下的節(jié)點被全部分配出去匣缘。
4猖闪、打印出分配信息,并提示用戶輸入“yes”確認是否按照打印出來的分配方式創(chuàng)建集群肌厨。
5培慌、輸入“yes”后,會執(zhí)行flush_nodes_config操作柑爸,該操作執(zhí)行前面的分配結果吵护,給master分配slot,讓slave復制master,對于還沒有握手(cluster meet)的節(jié)點馅而,slave復制操作無法完成祥诽,不過沒關系,flush_nodes_config操作出現(xiàn)異常會很快返回用爪,后續(xù)握手后會再次執(zhí)行flush_nodes_config原押。
6胁镐、給每個節(jié)點分配epoch偎血,遍歷節(jié)點,每個節(jié)點分配的epoch比之前節(jié)點大1盯漂。
7颇玷、節(jié)點間開始相互握手,握手的方式為節(jié)點列表的其他節(jié)點跟第一個節(jié)點握手就缆。
8帖渠、然后每隔1秒檢查一次各個節(jié)點是否已經(jīng)消息同步完成,使用ClusterNode的get_config_signature方法竭宰,檢查的算法為獲取每個節(jié)點cluster nodes信息空郊,排序每個節(jié)點,組裝成node_id1:slots|node_id2:slot2|...的字符串切揭。如果每個節(jié)點獲得字符串都相同狞甚,即認為握手成功。
9廓旬、此后會再執(zhí)行一次flush_nodes_config哼审,這次主要是為了完成slave復制操作。
10孕豹、最后再執(zhí)行check_cluster涩盾,全面檢查一次集群狀態(tài)。包括和前面握手時檢查一樣的方式再檢查一遍励背。確認沒有遷移的節(jié)點春霍。確認所有的slot都被分配出去了。
11叶眉、至此完成了整個創(chuàng)建流程终畅,返回[OK] All 16384 slots covered.。


4. 深入集群

集群的伸縮

添加節(jié)點(擴容)

  1. 準備節(jié)點

    image

啟動兩個新的 redis 實例, 分別監(jiān)聽不同端口 比如 70087009

我這里是在一臺主機上啟動 redis 實例

image.png
cp 7001.conf  7008.conf
sed -i 's/7001/7008/g'  7008.conf 
cp 7001.conf  7014.conf
sed -i 's/7001/7009/g'  7014.conf 
redis-server 7008.conf 
redis-server 7014.conf

2.加入集群中

添加一個新的節(jié)點為主節(jié)點

redis-trib.rb   add-node        new_host:new_port existing_host:existing_port

//     new_host:new_port 為新添加的節(jié)點信息
//    existing_host:existing_port 集群中任意節(jié)點的信息

添加一個新節(jié)點為從節(jié)點

redis-trib.rb   add-node     --slave  --master-id 主節(jié)點的 ID       new_host:new_port existing_host:existing_port

主節(jié)點 ID 可以使用如下命令查看竟闪,此命令還同時輸出了各個節(jié)點的角色

redis-trib.rb    check           host:port

//  host:port 為集群中任意節(jié)點的信息
image

例如:

加入一個主節(jié)點到集群中
redis-trib.rb add-node  127.0.0.1:7008 127.0.0.1:7002
image.png
  • 獲取剛才新加入的主節(jié)點信息
redis-trib.rb  check 127.0.0.1:7002
image.png

檢查前會先執(zhí)行l(wèi)oad_cluster_info_from_node方法离福,把所有節(jié)點數(shù)據(jù)load進來。load的方式為通過自己的cluster nodes發(fā)現(xiàn)其他節(jié)點炼蛤,然后連接每個節(jié)點妖爷,并加入nodes數(shù)組。接著生成節(jié)點間的復制關系。
load完數(shù)據(jù)后絮识,開始檢查數(shù)據(jù)绿聘,檢查的方式也是調(diào)用創(chuàng)建時候使用的check_cluster。

  • 添加從節(jié)點到集群中次舌,并指定他的主節(jié)點
redis-trib.rb add-node --slave --master-id 78e32beeb696819eb5718b0273723506761e645a 127.0.0.1:7009 127.0.0.1:7001
image.png

image.png
add-node命令可以將新節(jié)點加入集群熄攘,節(jié)點可以為master,也可以為某個master節(jié)點的slave彼念。

add-node    new_host:new_port existing_host:existing_port
          --slave
          --master-id <arg>
add-node有兩個可選參數(shù):
--slave:設置該參數(shù)挪圾,則新節(jié)點以slave的角色加入集群
--master-id:這個參數(shù)需要設置了--slave才能生效,--master-id用來指定新節(jié)點的master節(jié)點逐沙。如果不設置該參數(shù)哲思,則會隨機為節(jié)點選擇master節(jié)點。

add-node流程如下:
1吩案、通過load_cluster_info_from_node方法轉載集群信息棚赔,check_cluster方法檢查集群是否健康。
2徘郭、如果設置了--slave靠益,則需要為該節(jié)點尋找master節(jié)點。設置了--master-id残揉,則以該節(jié)點作為新節(jié)點的master胧后,如果沒有設置--master-id,則調(diào)用get_master_with_least_replicas方法冲甘,尋找slave數(shù)量最少的master節(jié)點绩卤。如果slave數(shù)量一致,則選取load_cluster_info_from_node順序發(fā)現(xiàn)的第一個節(jié)點江醇。load_cluster_info_from_node順序的第一個節(jié)點是add-node設置的existing_host:existing_port節(jié)點濒憋,后面的順序根據(jù)在該節(jié)點執(zhí)行cluster nodes返回的結果返回的節(jié)點順序村象。
3郊尝、連接新的節(jié)點并與集群第一個節(jié)點握手。
4蜡饵、如果沒設置–slave就直接返回ok条辟,設置了–slave黔夭,則需要等待確認新節(jié)點加入集群,然后執(zhí)行cluster replicate命令復制master節(jié)點羽嫡。
5本姥、至此,完成了全部的增加節(jié)點的流程杭棵。

  1. 向新加入的主節(jié)點中分配槽
redis-trib.rb reshard 127.0.0.1:7001
image.png
image
reshard         host:port
                --from <arg>
                --to <arg>
                --slots <arg>
                --yes
                --timeout <arg>
                --pipeline <arg>
host:port:這個是必傳參數(shù)婚惫,用來從一個節(jié)點獲取整個集群信息,相當于獲取集群信息的入口。
--from <arg>:需要從哪些源節(jié)點上遷移slot先舷,可從多個源節(jié)點完成遷移艰管,以逗號隔開,傳遞的是節(jié)點的node id蒋川,還可以直接傳遞--from all牲芋,這樣源節(jié)點就是集群的所有節(jié)點,不傳遞該參數(shù)的話捺球,則會在遷移過程中提示用戶輸入缸浦。
--to <arg>:slot需要遷移的目的節(jié)點的node id,目的節(jié)點只能填寫一個懒构,不傳遞該參數(shù)的話餐济,則會在遷移過程中提示用戶輸入耘擂。
--slots <arg>:需要遷移的slot數(shù)量胆剧,不傳遞該參數(shù)的話,則會在遷移過程中提示用戶輸入醉冤。
--yes:設置該參數(shù)秩霍,可以在打印執(zhí)行reshard計劃的時候,提示用戶輸入yes確認后再執(zhí)行reshard蚁阳。
--timeout <arg>:設置migrate命令的超時時間铃绒。
--pipeline <arg>:定義cluster getkeysinslot命令一次取出的key數(shù)量,不傳的話使用默認值為10螺捐。

遷移的流程如下:
1颠悬、通過load_cluster_info_from_node方法裝載集群信息。
2定血、執(zhí)行check_cluster方法檢查集群是否健康赔癌。只有健康的集群才能進行遷移。
3澜沟、獲取需要遷移的slot數(shù)量灾票,用戶沒傳遞--slots參數(shù),則提示用戶手動輸入茫虽。
4刊苍、獲取遷移的目的節(jié)點,用戶沒傳遞--to參數(shù)濒析,則提示用戶手動輸入正什。此處會檢查目的節(jié)點必須為master節(jié)點。
5号杏、獲取遷移的源節(jié)點婴氮,用戶沒傳遞--from參數(shù),則提示用戶手動輸入。此處會檢查源節(jié)點必須為master節(jié)點莹妒。--from all的話名船,源節(jié)點就是除了目的節(jié)點外的全部master節(jié)點。這里為了保證集群slot分配的平均旨怠,建議傳遞--from all渠驼。
6、執(zhí)行compute_reshard_table方法鉴腻,計算需要遷移的slot數(shù)量如何分配到源節(jié)點列表迷扇,采用的算法是按照節(jié)點負責slot數(shù)量由多到少排序,計算每個節(jié)點需要遷移的slot的方法為:遷移slot數(shù)量 * (該源節(jié)點負責的slot數(shù)量 / 源節(jié)點列表負責的slot總數(shù))爽哎。這樣算出的數(shù)量可能不為整數(shù)蜓席,這里代碼用了下面的方式處理:
n = (numslots/source_tot_slots*s.slots.length)
if i == 0
n = n.ceil
else
n = n.floor
這樣的處理方式會帶來最終分配的slot與請求遷移的slot數(shù)量不一致,這個BUG已經(jīng)在github上提給作者课锌,https://github.com/antirez/redis/issues/2990厨内。
7、打印出reshard計劃渺贤,如果用戶沒傳--yes雏胃,就提示用戶確認計劃。
8志鞍、根據(jù)reshard計劃瞭亮,一個個slot的遷移到新節(jié)點上,遷移使用move_slot方法固棚,該方法被很多命令使用统翩,具體可以參見下面的遷移流程。move_slot方法傳遞dots為true和pipeline數(shù)量此洲。
9厂汗、至此,就完成了全部的遷移任務黍翎。

補充

move_slot方法可以在線將一個slot的全部數(shù)據(jù)從源節(jié)點遷移到目的節(jié)點面徽,fix、reshard匣掸、rebalance都需要調(diào)用該方法遷移slot趟紊。
move_slot接受下面幾個參數(shù),
1碰酝、pipeline:設置一次從slot上獲取多少個key霎匈。
2、quiet:遷移會打印相關信息送爸,設置quiet參數(shù)铛嘱,可以不用打印這些信息暖释。
3、cold:設置cold墨吓,會忽略執(zhí)行importing和migrating球匕。
4、dots:設置dots帖烘,則會在遷移過程打印遷移key數(shù)量的進度亮曹。
5、update:設置update秘症,則會更新內(nèi)存信息照卦,方便以后的操作。

move_slot流程如下:
1乡摹、如果沒有設置cold役耕,則對源節(jié)點執(zhí)行cluster importing命令,對目的節(jié)點執(zhí)行migrating命令聪廉。fix的時候有可能importing和migrating已經(jīng)執(zhí)行過來瞬痘,所以此種場景會設置cold。
2锄列、通過cluster getkeysinslot命令图云,一次性獲取遠節(jié)點遷移slot的pipeline個key的數(shù)量.
3惯悠、對這些key執(zhí)行migrate命令邻邮,將數(shù)據(jù)從源節(jié)點遷移到目的節(jié)點。
4克婶、如果migrate出現(xiàn)異常筒严,在fix模式下,BUSYKEY的異常情萤,會使用migrate的replace模式再執(zhí)行一次鸭蛙,BUSYKEY表示目的節(jié)點已經(jīng)有該key了,replace模式可以強制替換目的節(jié)點的key筋岛。不是fix模式就直接返回錯誤了娶视。
5、循環(huán)執(zhí)行cluster getkeysinslot命令睁宰,直到返回的key數(shù)量為0肪获,就退出循環(huán)。
6柒傻、如果沒有設置cold孝赫,對每個節(jié)點執(zhí)行cluster setslot命令,把slot賦給目的節(jié)點红符。
7青柄、如果設置update伐债,則修改源節(jié)點和目的節(jié)點的slot信息。
8致开、至此完成了遷移slot的流程峰锁。

  1. 完成后觀察各主節(jié)點的數(shù)據(jù)槽的分配情況
image.png

減少節(jié)點(縮容)

image

縮容時的遷移槽

image

忘記節(jié)點操作

image
實驗

命令:

./redis-trib.rb  reshard --from   下線節(jié)點 ID  --to  集群中的任意主節(jié)點 ID  --slots   遷移到槽數(shù)   目前集群中任意節(jié)點 IP:端口
redis-trib.rb  reshard --from 78e32beeb696819eb5718b0273723506761e645a --to e00fedd6658c5cfedb2a27346a8e0e137b403536  --slots  4096  127.0.0.1:7001
未平均分配節(jié)點的遷移
未平均分配節(jié)點的遷移結果

注意:
需要把下線節(jié)點的槽數(shù)平均遷移到剩余的所有節(jié)點,所以需要分批分次執(zhí)行上面的命令双戳。
并且祖今,每次都集群中的主節(jié)點應該不同。

刪除節(jié)點

當我們使用 redis-trib.rb 工具時拣技,只需要在目前集群中的任意一個節(jié)點中執(zhí)行如下命令即可千诬。

redis-trib.rb del-node   集群中的任意host:port    刪除的節(jié)點的id

注意:
你應該始終先刪除從節(jié)點,再刪除主節(jié)點

image.png
image.png

del-node流程如下:
1膏斤、通過load_cluster_info_from_node方法轉載集群信息徐绑。
2、根據(jù)傳入的node id獲取節(jié)點莫辨,如果節(jié)點沒找到傲茄,則直接提示錯誤并退出。
3沮榜、如果節(jié)點分配的slot不為空盘榨,則直接提示錯誤并退出。
4蟆融、遍歷集群內(nèi)的其他節(jié)點草巡,執(zhí)行cluster forget命令,從每個節(jié)點中去除該節(jié)點型酥。如果刪除的節(jié)點是master山憨,而且它有slave的話,這些slave會去復制其他master弥喉,調(diào)用的方法是get_master_with_least_replicas郁竟,與add-node沒設置--master-id尋找master的方法一樣。
5由境、然后關閉該節(jié)點

刪除節(jié)點的小問題

在cluster不小心刪除某個節(jié)點后再加入節(jié)點是個很麻煩的事(刪除之前先把cluster分配的hashslot給重新分配一下(很重要))

通過 redis-trib.rb del-node 你的節(jié)點地址 bd5a40a6ddccbd46a0f4a2208eb25d2453c2a8db(你的node ID(可以通過 redis-trib.rb check 查看))刪除你的節(jié)點棚亩。

刪除完后要是想重新添加回去時發(fā)現(xiàn)用 redis-trib.rb add-node 你的節(jié)點地址 需要掛載的集群的節(jié)點 添加時會報錯,

[ERR] Node 192.168.XX.XX:XXXX is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

出現(xiàn)這個的原因是這個節(jié)點之前已經(jīng)加入過這個集群了虏杰,再次加入就會爆出這樣的錯誤讥蟆,你可以區(qū)配置節(jié)點的xxxx.conf文件里找到你保存的cluster-config-fil節(jié)點信息,找到然后刪除掉嘹屯,然后刪除掉該節(jié)點的數(shù)據(jù)保存RDB文件(要是開啟的AOF)也需一并刪除掉

然后運行 redis-trib.rb add-node 命令攻询,看是否可以加入集群。成功的話就不用往下看了

要是還是不行就得去連接到你的Redis redis-cli -h 192.168.XXX.XXX -p xxxx (你節(jié)點的地址個端口號)去flushdb一下州弟,清空數(shù)據(jù)庫钧栖,再次add-node應該就可以了低零。添加節(jié)點后記得給他分配hashslot(記得)

補充知識點

rebalance平衡集群節(jié)點slot數(shù)量

rebalance命令可以根據(jù)用戶傳入的參數(shù)平衡集群節(jié)點的slot數(shù)量,rebalance功能非常強大拯杠,可以傳入的參數(shù)很多掏婶,以下是rebalance的參數(shù)列表和命令示例。

rebalance       host:port
                --weight <arg>
                --auto-weights
                --threshold <arg>
                --use-empty-masters
                --timeout <arg>
                --simulate
                --pipeline <arg>

$ruby redis-trib.rb rebalance --threshold 1 --weight b31e3a2e=5 --weight 60b8e3a1=5 --use-empty-masters  --simulate 10.180.157.199:6379


host:port:這個是必傳參數(shù)潭陪,用來從一個節(jié)點獲取整個集群信息雄妥,相當于獲取集群信息的入口。
--weight <arg>:節(jié)點的權重依溯,格式為node_id=weight老厌,如果需要為多個節(jié)點分配權重的話,需要添加多個--weight <arg>參數(shù)黎炉,即--weight b31e3a2e=5 --weight 60b8e3a1=5枝秤,node_id可為節(jié)點名稱的前綴,只要保證前綴位數(shù)能唯一區(qū)分該節(jié)點即可慷嗜。沒有傳遞–weight的節(jié)點的權重默認為1淀弹。
--auto-weights:這個參數(shù)在rebalance流程中并未用到。
--threshold <arg>:只有節(jié)點需要遷移的slot閾值超過threshold庆械,才會執(zhí)行rebalance操作薇溃。具體計算方法可以參考下面的rebalance命令流程的第四步。
--use-empty-masters:rebalance是否考慮沒有節(jié)點的master缭乘,默認沒有分配slot節(jié)點的master是不參與rebalance的沐序,設置--use-empty-masters可以讓沒有分配slot的節(jié)點參與rebalance。
--timeout <arg>:設置migrate命令的超時時間忿峻。
--simulate:設置該參數(shù)薄啥,可以模擬rebalance操作,提示用戶會遷移哪些slots逛尚,而不會真正執(zhí)行遷移操作。
--pipeline <arg>:與reshar的pipeline參數(shù)一樣刁愿,定義cluster getkeysinslot命令一次取出的key數(shù)量绰寞,不傳的話使用默認值為10。

rebalance命令流程如下:
1铣口、load_cluster_info_from_node方法先加載集群信息滤钱。
2、計算每個master的權重脑题,根據(jù)參數(shù)--weight <arg>件缸,為每個設置的節(jié)點分配權重,沒有設置的節(jié)點叔遂,則權重默認為1他炊。
3争剿、根據(jù)每個master的權重,以及總的權重痊末,計算自己期望被分配多少個slot蚕苇。計算的方式為:總slot數(shù)量 * (自己的權重 / 總權重)。
4凿叠、計算每個master期望分配的slot是否超過設置的閾值涩笤,即--threshold <arg>設置的閾值或者默認的閾值。計算的方式為:先計算期望移動節(jié)點的閾值盒件,算法為:(100-(100.0*expected/n.slots.length)).abs蹬碧,如果計算出的閾值沒有超出設置閾值,則不需要為該節(jié)點移動slot炒刁。只要有一個master的移動節(jié)點超過閾值锰茉,就會觸發(fā)rebalance操作。
5切心、如果觸發(fā)了rebalance操作飒筑。那么就開始執(zhí)行rebalance操作,先將每個節(jié)點當前分配的slots數(shù)量減去期望分配的slot數(shù)量獲得balance值绽昏。將每個節(jié)點的balance從小到大進行排序獲得sn數(shù)組协屡。
6、用dst_idx和src_idx游標分別從sn數(shù)組的頭部和尾部開始遍歷全谤。目的是為了把尾部節(jié)點的slot分配給頭部節(jié)點肤晓。
sn數(shù)組保存的balance列表排序后,負數(shù)在前面认然,正數(shù)在后面补憾。負數(shù)表示需要有slot遷入,所以使用dst_idx游標卷员,正數(shù)表示需要有slot遷出盈匾,所以使用src_idx游標。理論上sn數(shù)組各節(jié)點的balance值加起來應該為0毕骡,不過由于在計算期望分配的slot的時候只是使用直接取整的方式削饵,所以可能出現(xiàn)balance值之和不為0的情況,balance值之和不為0即為節(jié)點不平衡的slot數(shù)量未巫,由于slot總數(shù)有16384個窿撬,不平衡數(shù)量相對于總數(shù),基數(shù)很小叙凡,所以對rebalance流程影響不大劈伴。
7、獲取sn[dst_idx]和sn[src_idx]的balance值較小的那個值握爷,該值即為需要從sn[src_idx]節(jié)點遷移到sn[dst_idx]節(jié)點的slot數(shù)量跛璧。
8严里、接著通過compute_reshard_table方法計算源節(jié)點的slot如何分配到源節(jié)點列表。這個方法在reshard流程中也有調(diào)用赡模,具體步驟可以參考reshard流程的第六步田炭。
9、如果是simulate模式漓柑,則只是打印出遷移列表教硫。
10、如果沒有設置simulate辆布,則執(zhí)行move_slot操作瞬矩,遷移slot,傳入的參數(shù)為:quiet=>true,:dots=>false,:update=>true锋玲。
11景用、遷移完成后更新sn[dst_idx]和sn[src_idx]的balance值。如果balance值為0后惭蹂,游標向前進1伞插。
12、直到dst_idx到達src_idx游標盾碗,完成整個rebalance操作媚污。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市廷雅,隨后出現(xiàn)的幾起案子耗美,更是在濱河造成了極大的恐慌,老刑警劉巖航缀,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件商架,死亡現(xiàn)場離奇詭異,居然都是意外死亡芥玉,警方通過查閱死者的電腦和手機蛇摸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來飞傀,“玉大人皇型,你說我怎么就攤上這事≡曳常” “怎么了?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵绞吁,是天一觀的道長幢痘。 經(jīng)常有香客問我,道長家破,這世上最難降的妖魔是什么颜说? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任购岗,我火速辦了婚禮,結果婚禮上门粪,老公的妹妹穿的比我還像新娘喊积。我一直安慰自己,他們只是感情好玄妈,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布乾吻。 她就那樣靜靜地躺著,像睡著了一般拟蜻。 火紅的嫁衣襯著肌膚如雪绎签。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天酝锅,我揣著相機與錄音诡必,去河邊找鬼。 笑死搔扁,一個胖子當著我的面吹牛爸舒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播稿蹲,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼扭勉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了场绿?” 一聲冷哼從身側響起剖效,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎焰盗,沒想到半個月后璧尸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡熬拒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年爷光,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澎粟。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛀序,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出活烙,到底是詐尸還是另有隱情徐裸,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布啸盏,位于F島的核電站重贺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜气笙,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一次企、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧潜圃,春花似錦缸棵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至崇堵,卻和暖如春型诚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸳劳。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工狰贯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赏廓。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓涵紊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幔摸。 傳聞我的和親對象是個殘疾皇子摸柄,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • redis集群分為服務端集群和客戶端分片,redis3.0以上版本實現(xiàn)了集群機制既忆,即服務端集群驱负,3.0以下使用客戶...
    hadoop_null閱讀 1,585評論 0 6
  • 前言 Redis 是我們目前大規(guī)模使用的緩存中間件,由于它強大高效而又便捷的功能患雇,得到了廣泛的使用跃脊。單節(jié)點的Red...
    Kevin_ZGJ閱讀 11,665評論 19 133
  • 本文檔匯總了多篇文章知識的結晶,整理出一份完整的Redis集群搭建教程苛吱,在本文最后也有注明摘自原文的地址酪术,如果原作...
    緯一閱讀 1,373評論 5 23
  • 轉自:https://www.zybuluo.com/phper/note/195558 前言 redis 是我們...
    yannhuang閱讀 1,672評論 0 2
  • 原文地址:http://www.reibang.com/p/9fe248e5a0ca Step 0 :集群概念 ...
    擦普洱閱讀 402評論 0 1