概述
Redis 在 3.0 之后開始支持 Cluster(集群)模式,特點如下:
- 支持節點的自動發現:可向集群動態添加節點,并自動融入
- 支持 slave-master 選舉和容錯:多個 master 宕機后,選舉出新的 master 繼續作業
- 在線分片:當有新的節點加入時,為新節點分配 slot 空間,從其他節點處獲取,并攜帶資料

搭建
以 Ubuntu 18.04.5,redis-7.0.4 為例,要想讓集群正常運作至少需要三個 master 節點,為了高可用,每個 master 節點至少要有一個 slave 節點,這里以一臺機器的六個埠作演示,分別是 7000、7001、7002、7003、7004、7005
創建多個 redis 組態檔(以其中一個為例,區別在于埠號和部分組態檔命名)
# 開啟遠程連接
bind * -::*
# 配置埠號,每個組態檔分別配置 7001/.../7005
port 7000
# 啟用守護行程
daemonize yes
# 行程組態檔名,redis_7000/.../redis_7005
pidfile "/var/run/redis_7000.pid"
# rdb檔案名,dump-7000/.../dump-7005
dbfilename dump-7000.rdb
# 開啟 AOF 持久化
appendonly yes
# aof檔案名,appendonly-7000/./appendonly-7005
appendfilename "appendonly-7000.aof"
# 開啟集群模式
cluster-enabled yes
# 節點組態檔名,nodes-7000/.../nodes-7005
cluster-config-file nodes-7000.conf
# 節點超時時間
cluster-node-timeout 15000
創建 7000-7005 檔案夾,把對應的組態檔放進去

指定不同組態檔啟動六個節點,例如
./redis-server 7000/redis.conf
將六個節點組合成集群,在組合之前,請確保以下條件:
- 所有節點正常啟動后
- nodes-xxx.conf 檔案都正常生成
- 如果有開啟防火墻,放行 7000-7005、17000-17005 埠,前者用于客戶端通信,后者用于集群間通信
# redis會自動規劃集群部署,例如這里會以前三個為主節點,后三個分別作從節點
redis-cli --cluster create --cluster-replicas 1 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
使用 redis-cli --cluster check 命令來查看節點資訊
# 后面的ip:port使用集群任一節點即可
redis-cli --cluster check 127.0.0.1:7000
也可以通過 redis-cli 連接任一節點,使用如下命令查看節點資訊
# 使用普通方式登錄,存盤資料時可能會出現MOVED重定向操作,所以應該加上-c以集群方式登錄
redis-cli -c -p 7000
# 查看節點所在集群資訊
cluster nodes
一般使用 cluster nodes 命令,資訊更詳細

以 7000 為例,講解每項的含義:
- id:28df8f39d35ad2ddaeddad2ef0b11c77f381a26a,節點 ID,這個值在節點啟動時創建,作為唯一標識
- ip:port:127.0.0.1:7000@17000,節點的通信地址
- flags:myself,master:逗號分割的標記位,可能的值及含義如下:
- myself:當前連接的節點
- master:節點是 master
- slave: 節點是 slave
- fail?:當前節點無法聯系,但邏輯上是可達的(非 FAIL 狀態)
- fail:節點處于 FAIL 狀態.,大部分節點都無法與其取得聯系,則會將該節點由 PFAIL 狀態升級為 FAIL 狀態
- handshake:還未取得信任的節點,當前正在與其進行握手
- noaddr:沒有地址的節點(No address known for this node)
- noflags:連個標記都沒有(No flags at all)
- master:28df8f39d35ad2ddaeddad2ef0b11c77f381a26a,這里是 7004 節點的資訊,因為該節點是 slave 節點,所以會列出所屬 master 節點的 ID,也就是 7000
- ping-sent:-0,最近一次發送 ping 的時間,這個時間是一個 unix 毫秒時間戳,0 代表沒有發送過
- pong-recv:1661445823000,最近一次收到pong的時間,使用 unix 時間戳表示
- config-epoch:1,節點的 epoch 值(如果該節點是從節點,則為其主節點的 epoch 值),每當節點發生失敗切換時,都會創建一個新的且遞增的 epoch 值,如果多個節點競爭同一個哈希槽,epoch 值更高的節點更容易搶奪到
- link-state:connected,集群總線使用的鏈接的狀態,我們使用這個鏈接與集群中其他節點進行通信,值可以是 connected 或 disconnected
- slot:0-5460,哈希槽值或者一個哈希槽范圍,有關哈希槽值的內容在下面講解
哈希槽(slot)
Redis 集群把把所有的物理節點(向外提供服務的 master)映射到 [0 - 16383] slot 上,即所有 master 均分 16384 大小的 slot 空間,每個 master 占有一定的 slot 空間
當存盤資料時,首先會對 key 使用 CRC16 演算法進行加密,將得到的值 mod 16384,這樣一來 key 的值始終在 0-16383 之間,Redis 則根據 key 值將其放入對應范圍的節點,比如算出來的 key 值是 3000,7000 節點的 slot 空間是 [0 - 5460],那么就會放到 7000 節點,平均集群的壓力
同理,當獲取資料時,也會對 Key 進行同樣的計算,根據得到的值去對應的節點獲取資料
注意:slot 不是值集群所能存盤資料的容量,16384 也并不是說只能存 16384 個鍵,它僅僅表示每個節點的一個存盤范圍,key 值落到那個范圍,就找對應范圍的節點服務
以之前搭建的集群為例,客戶端連接 7000 節點,存盤一個測驗資料,Redis 會自動計算 Key 值,如果計算結果在 7001 節點的范圍,則重定向到 7001 節點存盤

獲取值也是同理

其他命令
向集群動態添加主節點,先啟動 7006 服務,再執行以下命令:
# redis-cli --cluster add-node [新加入節點] [原始集群中任意節點]
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
向集群動態添加從節點,先啟動 7007 服務,再執行以下命令:
# redis-cli --cluster add-node --cluster-slave [--master-id master節點id] [新加入節點] [原始集群中任意節點]
# 如果沒有指定主節點,redis會隨機給副本數少的主節點添加當前副本節點
redis-cli --cluster add-node --cluster-slave 127.0.0.1:7007 127.0.0.1:7000
這個時候我們查看集群狀態,會發現新添加的 7006 節點沒有分配 slot

沒有 slot 是不能處理資料的,所以需要重新分配集群 slot
# redis-cli --cluster reshard [原始集群中任意節點] --cluster-from [源slot節點id,多個id用逗號分隔] --cluster-to [接收slot節點id] --cluster-slots [分配slot大小]
redis-cli --cluster reshard 127.0.0.1:7000 --cluster-from 28df8f39d35ad2ddaeddad2ef0b11c77f381a26a --cluster-to a8e9320b93498f2dcdc689e61ffec73f79d3a6d6 --cluster-slots 1024
洗掉節點
# redis-cli --cluster del-node [集群中任意節點] [洗掉節點id]
redis-cli --cluster del-node 127.0.0.1:7000 ac949f85aa8becb811d1f0a46d18f41075e63051
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/502954.html
標籤:其他
上一篇:mysql常用操作匯總
