title: redis集群
date: 2021-01-14 20:12:14
categories: redis
tags:
- redis cluster
description: 集群模式是redis的分布式解決方案
redis集群數(shù)據(jù)分區(qū)
一個集群必須要解決數(shù)據(jù)分布的問題用爪,常用的方法有哈希分區(qū)顽照、順序分區(qū)无畔。哈希分區(qū)的特點是離散度好數(shù)據(jù),而順序分區(qū)則可以提供順序訪問参袱。
redis采用虛擬槽分區(qū)的方式來將數(shù)據(jù)分區(qū),一共16384個槽电谣,所有的鍵根據(jù)哈希函數(shù)slog=CRC16(key)&16383,映射到0~16383整數(shù)槽內(nèi)抹蚀。
每一個節(jié)點負責維護一部分槽剿牺,以及槽所對應的鍵值數(shù)據(jù)
Redis虛擬槽分區(qū)的特點:
- 解耦數(shù)據(jù)與節(jié)點之間的關系
- 節(jié)點自身維護槽的映射關系,不需要客戶端或者代理服務維護槽分區(qū)元數(shù)據(jù)
- 支持節(jié)點环壤、槽晒来、鍵之間的映射查詢,用于數(shù)據(jù)路由郑现、在線伸縮等場景
redis集群功能缺陷:
- key批量操作支持有限湃崩,只能支持具有相同slot值的key執(zhí)行批量操作
- 同理事物也同樣只支持同一節(jié)點上的事物操作
- key作為數(shù)據(jù)分區(qū)的最小粒度,因此不能將一個大的鍵值對象如hash接箫、list等拆分到不同的節(jié)點分布
- 不支持多數(shù)據(jù)庫攒读,只有一個db0
- 復制結(jié)構(gòu)只支持一層、從節(jié)點只能復制主節(jié)點辛友,不支持樹狀分布
集群搭建
-
準備好6個節(jié)點:
redis-6379.conf redis-6380.conf redis-6381.conf redis-6382.conf redis-6383.conf redis-6384.conf $> cat redis-6379.conf port 6379 cluster-enabled yes cluster-node-timeout 15000 # 如果沒有配置薄扁,則會在啟動后生成一份 cluster-config-file "nodes-6379.conf" logfile "/redis/logs/redis-6379.log" dbfilename "dump-6379.rdb"
-
啟動集群
redis-server conf/redis-6379.conf
目前每個節(jié)點都只能識別自己的節(jié)點新,因為現(xiàn)在彼此不知道對方的存在127.0.0.1:6379> CLUSTER NODES 6e39c9aba1bb22c51e1fb6d37aeda4174a782eac :6379@16379 myself,master - 0 0 0 connected
手動建立集群
-
節(jié)點握手
節(jié)點握手是讓當前節(jié)點感知到另一個節(jié)點废累,由客戶端發(fā)起命令,cluster meet {ip} {port}
節(jié)點握手
節(jié)點握手后集群還不能正常工作邓梅,因為還沒有分配槽,這個時候?qū)懨顣l(fā)現(xiàn)失斠乇酢:
```sh
127.0.0.1:6379> set hello redis
(error) CLUSTERDOWN Hash slot not served
# 查看集群信息日缨,發(fā)現(xiàn)state是fail狀態(tài),分配的槽slot為0
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:2
cluster_stats_messages_ping_sent:490
cluster_stats_messages_pong_sent:210
cluster_stats_messages_meet_sent:7
cluster_stats_messages_sent:707
cluster_stats_messages_ping_received:210
cluster_stats_messages_pong_received:198
cluster_stats_messages_received:408
```
-
分配槽
之前說過驼修,redis集群把所有的數(shù)據(jù)映射到16384個槽中殿遂,而這些槽如何分配诈铛,是要通過配置來決定乙各。只有這些槽都被分配好了
redis集群才能響應命令,通過cluster addslots
命令為節(jié)點分槽幢竹。(正常做法應該使用create命令)./redis-cli 9 -p 6381 cluster addslots {0..5461} ./redis-cli 9 -p 6381 cluster addslots {5462..10922} ./redis-cli 9 -p 6381 cluster addslots {10923..16383}
此時集群已經(jīng)可用了耳峦,為了集群的高可用,我們再為每一個節(jié)點分配一個從節(jié)點焕毫。
- 配置集群從節(jié)點 cluster replicate {id}
CLUSTER REPLICATE 6e39c9aba1bb22c51e1fb6d37aeda4174a782eac
注意后面跟的是clusterid
以上步驟依照Redis協(xié)議手動建立了一個集群蹲坷,便于理解集群建立的過程驶乾,但比較繁瑣且容易出錯,因此循签,官方自帶工具方便我們快速搭建集群级乐,之前我們使用
redis-trib.rb來創(chuàng)建,在Redis5.0中創(chuàng)建集群已經(jīng)使用“redis-cli”來實現(xiàn)县匠,所以redis-trib.rb的方式已經(jīng)被拋棄
利用cluster create快速搭建集群
和上面的步驟一樣先配置六個不同的配置文件风科,再啟動6個進程,不過節(jié)點握手和分配槽這個步驟不一樣乞旦,我們是有redis-cli來簡化操作
redis-cli --cluster subcommand [args] [opt]
./redis-cli --cluster create --cluster-replicas 1 127.0.0.1:6380 127.0.0.1:6379 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384
最后輸出結(jié)果
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:6383 to 127.0.0.1:6380
Adding replica 127.0.0.1:6384 to 127.0.0.1:6379
Adding replica 127.0.0.1:6382 to 127.0.0.1:6381
# 優(yōu)化
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 6e2da8e45d804b47fe599d121682e6a394c527ef 127.0.0.1:6380
slots:[0-5460] (5461 slots) master
M: 4aa937577181f82ce88b1c909a519ca03963ab21 127.0.0.1:6379
slots:[5461-10922] (5462 slots) master
M: 07b085e9e9750e5d0c319f3c099d70acda84f6fb 127.0.0.1:6381
slots:[10923-16383] (5461 slots) master
S: 0c1c1ce2bf3c890396da31a1b536adcd32e2766a 127.0.0.1:6382
replicates 07b085e9e9750e5d0c319f3c099d70acda84f6fb
S: 36b71d82eaccae49f0aff395fa3cae03c1adcc0f 127.0.0.1:6383
replicates 6e2da8e45d804b47fe599d121682e6a394c527ef
S: 4885dcbd061e28d969eb8d2ae893f256c9c79401 127.0.0.1:6384
replicates 4aa937577181f82ce88b1c909a519ca03963ab21
# 確認部署
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
# 其他校驗信息
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered
可以看到:
- redis-cli命令會對節(jié)點分配進行優(yōu)化贼穆,比如主從使用不同的ip等
- 部署方案需要人工再確認一遍
- 會確保所有槽都被分配成功
集群內(nèi)通信
redis集群采用p2p的Gossip協(xié)議,類似留言兰粉,通過彼此不斷地通信交換信息故痊,最后所有節(jié)點直到集群完整的信息。
- 集群中每個節(jié)點都會單獨開辟一個TCP通道玖姑,用于節(jié)點之間彼此通信愕秫,通信端口號是在基礎上加上10000.
- 每個節(jié)點在固定周期內(nèi)通過特定規(guī)則選擇幾個節(jié)點發(fā)送ping消息
- 接收到ping消息的節(jié)點用pong消息作為響應
特定規(guī)則是什么?
由于內(nèi)部需要頻繁的進行節(jié)點信息交換焰络,ping/pong消息會攜帶當前節(jié)點和部分其他節(jié)點的狀態(tài)數(shù)據(jù)豫领,Redis集群內(nèi)
節(jié)點每秒執(zhí)行10次,因此節(jié)點每次選擇通信的節(jié)點列表非常重要舔琅。太多會影響帶寬等恐,太少又不能做到及時交換信息。因此redis采用過程如下:
[圖片上傳失敗...(image-eae61e-1611843829725)]
消息的數(shù)據(jù)量
- 消息頭:固定占用myslots[CLUSTER_SLOTS/8],2kb
- 消息體:默認是1/10個其他節(jié)點的信息备蚓,最少3個课蔬,醉倒total-2個,所以消息的大小跟節(jié)點數(shù)有關郊尝。
集群伸縮
集群伸縮就是利用槽在節(jié)點間的移動遭居,也就是數(shù)據(jù)在各個節(jié)點的移動。
擴容
-
準備節(jié)點
> cp redis-6384.conf redis-6385.conf > sed -i 's/6384/6385/' redis-6385.conf > ./redis/src/redis-server config/redis-6385.conf
-
加入集群
> ./redis/src/redis-cli --cluster add-node localhost:6385 localhost:6384 >>> Adding node 127.0.0.1:6385 to cluster 127.0.0.1:6384 >>> Performing Cluster Check (using node 127.0.0.1:6384) S: 4885dcbd061e28d969eb8d2ae893f256c9c79401 127.0.0.1:6384 slots: (0 slots) slave replicates 4aa937577181f82ce88b1c909a519ca03963ab21 M: ce5e60a517c8714d52b82d9e24b71d2f5a1868c4 127.0.0.1:6385 slots: (0 slots) master S: 0c1c1ce2bf3c890396da31a1b536adcd32e2766a 127.0.0.1:6382 slots: (0 slots) slave replicates 07b085e9e9750e5d0c319f3c099d70acda84f6fb M: 07b085e9e9750e5d0c319f3c099d70acda84f6fb 127.0.0.1:6381 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: 36b71d82eaccae49f0aff395fa3cae03c1adcc0f 127.0.0.1:6383 slots: (0 slots) slave replicates 6e2da8e45d804b47fe599d121682e6a394c527ef M: 6e2da8e45d804b47fe599d121682e6a394c527ef 127.0.0.1:6380 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: 4aa937577181f82ce88b1c909a519ca03963ab21 127.0.0.1:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. # meet 節(jié)點 >>> Send CLUSTER MEET to node 127.0.0.1:6385 to make it join the cluster. [OK] New node added correctly # 檢查node情況,發(fā)現(xiàn)已經(jīng)加入 > cluster nodes 4aa937577181f82ce88b1c909a519ca03963ab21 127.0.0.1:6379@16379 myself,master - 0 1611108761000 2 connected 5461-10922 36b71d82eaccae49f0aff395fa3cae03c1adcc0f 127.0.0.1:6383@16383 slave 6e2da8e45d804b47fe599d121682e6a394c527ef 0 1611108764049 5 connected 07b085e9e9750e5d0c319f3c099d70acda84f6fb 127.0.0.1:6381@16381 master - 0 1611108763000 3 connected 10923-16383 ce5e60a517c8714d52b82d9e24b71d2f5a1868c4 127.0.0.1:6385@16385 master - 0 1611108763046 0 connected 0c1c1ce2bf3c890396da31a1b536adcd32e2766a 127.0.0.1:6382@16382 slave 07b085e9e9750e5d0c319f3c099d70acda84f6fb 0 1611108762000 4 connected 6e2da8e45d804b47fe599d121682e6a394c527ef 127.0.0.1:6380@16380 master - 0 1611108765050 1 connected 0-5460 4885dcbd061e28d969eb8d2ae893f256c9c79401 127.0.0.1:6384@16384 slave 4aa937577181f82ce88b1c909a519ca03963ab21 0 1611108763000 6 connected
-
遷移槽
繼續(xù)使用redis-cli cluster 命令钠绍,使用reshard參數(shù)遷移槽> ./redis/src/redis-cli --cluster reshard 127.0.0.1:6379 # 進行一系列校驗后提示輸入要遷移的槽的個數(shù)鬓梅,輸入4096 How many slots do you want to move (from 1 to 16384) 4069 # 接著會提示輸入目標節(jié)點,也就是新加入的節(jié)點id what is the receiveing node ID ? ce5e60a517c8714d52b82d9e24b71d2f5a1868c4 # 然后會提示輸入源節(jié)點的ID况凉,也就是說可以只轉(zhuǎn)移部分節(jié)點的槽 Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1: 24b9eea3f3797a68e33100dccfdbfc57693f7a4b Source node #2: 07b085e9e9750e5d0c319f3c099d70acda84f6fb Source node #3: 6e2da8e45d804b47fe599d121682e6a394c527ef # redis會打印每個槽的遷移計劃谚鄙,會再確認一次,確認后會打印遷移過程刁绒,最后自動退出
從redis的輸出就可以看出闷营,redis的遷移過程是一個一個槽遷移的,槽遷移過程如下:
槽遷移過程 -
檢查槽的均衡性
> ./redis/src/redis-cli --cluster rebalance 127.0.0.1:6379 >>> Performing Cluster Check (using node 127.0.0.1:6379) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. *** No rebalancing needed! All nodes are within the 2.00% threshold.
說明遷移之后主節(jié)點負責的槽數(shù)量差異在2%以內(nèi),相對均勻傻盟,無需調(diào)整
添加從節(jié)點
準備一個6386節(jié)點速蕊,步驟與前面一樣,然后在該節(jié)點上執(zhí)行cluster replicate {masterId}
娘赴,注意集群模式下沒有salveof命令
集群收縮
原理和方法和擴容是一樣的规哲,都是重新分片reshard,只不過之前是把已有節(jié)點的數(shù)據(jù)遷移一部分到新節(jié)點诽表。而收縮則是把要下線節(jié)點的數(shù)據(jù)遷移到其他節(jié)點媳叨。
執(zhí)行方法與擴容一樣,都是用reshard关顷。 注意del-node是刪除空節(jié)點的命令糊秆,如果有槽是不能刪除的。
下線后议双,為了讓其他節(jié)點忘記下線節(jié)點痘番,也就是避免繼續(xù)和下線節(jié)點交換信息,這個時候可以用del-node 命令平痰。
請求路由
在集群模式下汞舱,Redis接受任何鍵相關的命令都要先計算鍵對應的槽(每個集群節(jié)點在交換信息時都會發(fā)送槽信息,因此每個節(jié)點都知道所有槽和節(jié)點的對應關系)宗雇,再根據(jù)槽找出相應的節(jié)點昂芜,如果節(jié)點是自身,則處理命令赔蒲,如果不是則恢復MOVED重定向錯誤泌神。通知客戶端請求正確的節(jié)點
127.0.0.1:6386> set key:test:1 value-1
(error) MOVED 5191 127.0.0.1:6380
使用redis-cli工具時,可以加入-c參數(shù)支持自動重定向舞虱,也就是不用手動切換節(jié)點欢际。原理是redis-cli客戶端再收到MOVED信息時,再次發(fā)起請求矾兜。
redis節(jié)點對于不屬于它的鍵命令损趋,只會回復重定向響應,并不負責轉(zhuǎn)發(fā)椅寺。重定向的過程由客戶端實現(xiàn)
./redis/src/redis-cli -p 6386 -c
127.0.0.1:6386> set key:test:1 value-1
-> Redirected to slot [5191] located at 127.0.0.1:6380
OK
如果鍵內(nèi)容包含{}大括號字符浑槽,則計算槽的有效部分是括號內(nèi)的內(nèi)容,其他內(nèi)容不會被計算返帕,如果不包含則所有內(nèi)容都會加入計算桐玻,利用這一點我們可以優(yōu)化批量數(shù)據(jù),比如哈希類型的溉旋,我們?nèi)绻褂胔get的時候畸冲,如果鍵列表不再同一個槽中會報錯,這個時候可以用hash_tag來使該哈希表中所有的鍵都在同一個槽中观腊。
100.101.71.99:6380> CLUSTER KEYSLOT key:test:111
(integer) 10050
100.101.71.99:6380> CLUSTER KEYSLOT key:{test}:111
(integer) 6918
100.101.71.99:6380> CLUSTER KEYSLOT key:{test}:112
(integer) 6918
100.101.71.99:6380> CLUSTER KEYSLOT key:{test}:22
(integer) 6918
- ASK重定向
與MOVED重定向不一樣邑闲,ASK重定向,是發(fā)生在槽遷移過程中梧油,一部分遷移完成苫耸,一部分沒有遷移成功,客戶端根據(jù)本地slots緩存發(fā)送命令到源節(jié)點儡陨,但其實已經(jīng)發(fā)送到了目標節(jié)點褪子,因此會回復(error)ASK {slot}{targetIP}:{targetIP}
Smart客戶端
顯然每次通過重定向來完成操作,會造成很大的IO浪費骗村。smart客戶端則通過內(nèi)部維護槽和節(jié)點的關系嫌褪,本地就可以實現(xiàn)鍵和節(jié)點的查找。而MOVED重定向則只是協(xié)助客戶端維護槽和節(jié)點之間的關系胚股。
- jedis客戶端
故障轉(zhuǎn)移
與哨兵模式一樣笼痛,Redis集群模式也要解決分布式通用的部分失敗的問題。
-
故障發(fā)現(xiàn)
Redis集群內(nèi)通過ping/pong消息實現(xiàn)節(jié)點通信琅拌,消息不止攜帶節(jié)點槽信息缨伊,還攜帶有其他狀態(tài),比如主從節(jié)點狀態(tài)进宝、節(jié)點故障燈刻坊。當集群內(nèi)某個節(jié)點出現(xiàn)問題時,就會通過消息傳播
與哨兵模式類似党晋,存在主觀下線和客觀下線兩種狀態(tài)-
主觀下線:每個節(jié)點都會定期向其他節(jié)點發(fā)送ping消息谭胚,如果節(jié)點在cluster-node-timetout時間內(nèi)沒有收到pong消息,則該發(fā)送節(jié)點未玻,就會認為對端存在故障漏益。把接受節(jié)點標記為主觀下線狀態(tài)(pfail)。
typedef struct clusterState { clusterNode *myself; /* 自身節(jié)點 / dict *nodes;/* 當前集群內(nèi)所有節(jié)點的字典集合深胳,key為節(jié)點ID绰疤,value為對應節(jié)點ClusterNode結(jié)構(gòu) */ ... } clusterState;字典nodes屬性中的clusterNode結(jié)構(gòu)保存了節(jié)點的狀態(tài),關鍵屬性如下: typedef struct clusterNode { int flags; /* 當前節(jié)點狀態(tài),如:主從角色,是否下線等 */ mstime_t ping_sent; /* 最后一次與該節(jié)點發(fā)送ping消息的時間 */ mstime_t pong_received; /* 最后一次接收到該節(jié)點pong消息的時間 */ ... } clusterNode;
客觀下線
當某個節(jié)點判斷另一個節(jié)點主觀下線后舞终,相應的節(jié)點狀態(tài)會跟隨消息在集群內(nèi)傳播轻庆。當半數(shù)以上持有槽的主節(jié)點都標記某個節(jié)點是主觀下線時,觸發(fā)客觀下線流程
-
故障恢復
當故障節(jié)點變?yōu)榭陀^下線后敛劝,如果下線節(jié)點是持有槽的主節(jié)點余爆,則需要選擇一個從節(jié)點來替換它,從而保證高可用夸盟。下線主節(jié)點的所有從節(jié)點承擔故障恢復的義務蛾方。當從節(jié)點通過內(nèi)部
定時任務發(fā)現(xiàn)主節(jié)點客觀下線時,就會觸發(fā)故障恢復流程:
資格檢查
判斷當前節(jié)點是否有資格替換主節(jié)點,判斷依據(jù)是桩砰,從節(jié)點與主節(jié)點斷線時間是否超過cluster-node-time*cluster-slave-validity-factor拓春。如果超過則不具備3準備選舉時間
當從節(jié)點具備故障轉(zhuǎn)移資格后,更新觸發(fā)故障選舉的時間亚隅,只有到達該時間后才能執(zhí)行后續(xù)流程硼莽。這里之所以要采用延時觸發(fā)機制,主要是多個從節(jié)點有不同的優(yōu)先級煮纵,也就是根據(jù)他們的優(yōu)先級來觸發(fā)故障選舉懂鸵,優(yōu)先級更高的更容易成為主節(jié)點,而優(yōu)先級的判斷就是通過offset(復制的偏移)行疏。發(fā)起選舉
更新配置的epoch匆光,每個主節(jié)點自身維護一個epoch表示當前主節(jié)點的版本,所有主節(jié)點的epoch都不相等酿联,從節(jié)點會復制主節(jié)點的epoch终息。整個集群有一個最大的epoch,也就是集群epoch货葬。epoch會隨著消息的傳遞傳播下去采幌,
如果epoch相等,那么會根據(jù)nodeid大小來更新震桶,nodeid更大的會使當前集群epoch遞增休傍,并且賦值給自己的epoch。每當新節(jié)點加入蹲姐、槽節(jié)點映射沖突磨取、從節(jié)點投票選舉沖突時都會更新epoch。
更新后會在集群內(nèi)廣播選舉消息(FAILOVER_AUTH_REQUEST)柴墩,并記錄已發(fā)送過消息的狀態(tài)忙厌。保證該節(jié)點在一個epoch只能發(fā)起一次選舉。選舉投票
只有持有槽的主節(jié)點才會處理故障選舉消息江咳,也就是上面說的REQUET逢净,在選舉過程中每個節(jié)點在同一個epoch中只有一張選票,當收到第一個從節(jié)點消息是歼指,就會回復ACK消息投出自己的選票爹土,之后不會再響應選舉請求。
最終收到投票數(shù)大于一般的從節(jié)點會成為主節(jié)點踩身。-
替換主節(jié)點
當從節(jié)點收到足夠多的選票后胀茵,觸發(fā)替換主節(jié)點操作:- 取消復制,成為主節(jié)點
- 執(zhí)行clusterDelSlot操作挟阻,撤銷故障節(jié)點負責的槽琼娘,并執(zhí)行clusterAddSlot把這些槽委派給自己
- 向集群廣播自己的pong消息峭弟。通知其他節(jié)點更新信息。
-
故障轉(zhuǎn)移時間
- 主觀下線識別時間=cluster-node-timeout
- 傳播時間<=cluster-node-timeout/2
- 從節(jié)點轉(zhuǎn)移時間<=1000毫秒
-
模擬故障轉(zhuǎn)移:
# 主節(jié)點日志 128026:M 28 Jan 2021 19:56:59.247 * Clear FAIL state for node 4aa937577181f82ce88b1c909a519ca03963ab21: is reachable again and nobody is serving its slots after some time. 128026:M 28 Jan 2021 19:56:59.247 # Cluster state changed: ok 128026:M 28 Jan 2021 19:58:38.299 * Marking node 4aa937577181f82ce88b1c909a519ca03963ab21 as failing (quorum reached). 128026:M 28 Jan 2021 19:58:38.299 # Cluster state changed: fail 128026:M 28 Jan 2021 19:58:38.809 # Failover auth granted to 4885dcbd061e28d969eb8d2ae893f256c9c79401 for epoch 9 128026:M 28 Jan 2021 19:58:38.848 # Cluster state changed: ok 128026:M 28 Jan 2021 19:58:45.127 * Clear FAIL state for node 4aa937577181f82ce88b1c909a519ca03963ab21: master without slots is reachable again. # 從節(jié)點日志 128093:S 28 Jan 2021 19:58:38.805 # Starting a failover election for epoch 9. 128093:S 28 Jan 2021 19:58:38.812 # Failover election won: I'm the new master. 128093:S 28 Jan 2021 19:58:38.812 # configEpoch set to 9 after successful failover 128093:M 28 Jan 2021 19:58:38.812 # Setting secondary replication ID to 2609636bd51ab7c2e436ee5653a8bf8a7445eefa, valid up to offset: 113. New replication ID is 3231e43113314a13c4878d95263a718da8fb305d 128093:M 28 Jan 2021 19:58:38.812 * Discarding previously cached master state. 128093:M 28 Jan 2021 19:58:38.812 # Cluster state changed: ok 128093:M 28 Jan 2021 19:58:45.128 * Clear FAIL state for node 4aa937577181f82ce88b1c909a519ca03963ab21: master without slots is reachable again.
集群運維
集群完整性
默認情況下當集群16384個槽任何一個沒有指派到節(jié)點上脱拼,則執(zhí)行任何明林過度會報錯瞒瘸。這是對集群的一種保護,但當主節(jié)點下線時挪拟,從故障發(fā)現(xiàn)到完成轉(zhuǎn)移這個過程挨务,整個集群時不可用狀態(tài)的击你,很多業(yè)務場景無法容忍這種情況
因此可以將參數(shù)cluster-require-full-coverage配置為no玉组,當主節(jié)點故障時,只影響它負責槽的相關命令執(zhí)行丁侄,不會影響其他節(jié)點惯雳。帶寬消耗
官方建議規(guī)模在1000以內(nèi),不然會造成大量網(wǎng)絡帶寬鸿摇,2適當提交cluster-node-timeout降低消息發(fā)送頻率石景、3盡量均勻的部署節(jié)點。Pub/Sub廣播問題
盡量使用sentinel模式使用廣播拙吉,集群模式會造成消息在所有節(jié)點廣播一遍潮孽,加重帶寬負擔。-
集群傾斜
- 節(jié)點和槽分配不均筷黔,可以使用rebalance命令往史,進行平衡
- 不同槽對應鍵數(shù)量差異過大,一般使用CRC16哈希算法會相對均勻佛舱,但如果大量使用hash_tag時椎例,就會產(chǎn)生多個鍵映射到同一個槽的情況。
- 集合對象包含大量元素请祖,可以通過redis-cli bigkeys命令識別
- 內(nèi)存配置不一致
手動故障轉(zhuǎn)移
Redis提供了手動故障轉(zhuǎn)移功能订歪,比如需要切換設備,重新調(diào)整部署方案的時候肆捕,可能會用到(直接kill會導致一定時間的不可用)刷晋。使用cluster failover命令