redis cluster保存的數據量及吞吐量跟集群的規(guī)模相關,Redis 官方給出了 Redis Cluster?
的規(guī)模上限,是一個集群運行1000 個實例。為什么規(guī)定集群規(guī)模上限呢?
集群規(guī)模越大越好?
隨著集群數量的越來越多,各實例間的通信開銷也隨之越來越大,到達一定數量,
集群的吞吐量反而下降,所以集群的規(guī)模并不是越大越好。redis每個實例上都會
保存slot和實例的映射關系slot映射表,以及自身的狀態(tài)信息用來跟別的實例通信
告知自身狀態(tài)。
Gossip 協議
每個實例之間會按照一定的頻率,從集群中隨機挑選一些實例,把PING消息發(fā)送
給挑選出來的實例,用來檢測這些實例是否在線,并交換彼此的狀態(tài)信息。PING 消息中封
裝了發(fā)送消息的實例自身的狀態(tài)信息、部分其它實例的狀態(tài)信息,以及 Slot 映射表。
一個實例在接收到 PING 消息后,會給發(fā)送 PING 消息的實例,發(fā)送一個 PONG 消
息,PONG 消息包含的內容和 PING 消息一樣,gossip協議可以保證集群在經過一段時間
后,各實例都互相擁有其信息,當集群有實例加入退出或者slot變更時,各實例也可以通過
ping pong消息互相通知,完成消息同步
Gossip消息大小
Redis 實例發(fā)送的 PING 消息的消息體是由 clusterMsgDataGossip 結構體組成的

每個實例在發(fā)送一個 Gossip 消息時,除了會傳遞自身的狀態(tài)信息,默認還會傳遞集群十分
之一實例的狀態(tài)信息,對于一個包含了 1000 個實例的集群來說,每個實例發(fā)送一個?
PING 消息時,會包含 100 個實例的狀態(tài)信息,總的數據量是 10400 字節(jié),再加上發(fā)送
實例自身的信息,一個 Gossip 消息大約是 10KB,再加上一個存儲slot表的bitmap2kB,
所以一個ping消息大約是12kb,加上pong消息,共24Kb,相較于我們平常處理的業(yè)務,
24kb算是很大了,隨著集群規(guī)模的增大,心跳信息的的增多,會占據集群的部分帶寬,
進而影響到集群的吞吐量
實例間通信頻率
redis cluster 會默認每秒從本地的實例列表隨機挑選5個,然后從其中選出一個最久
沒有通信的實例,進而發(fā)送ping消息,還會按照100ms一次的頻率掃描本地實例列表,
一旦發(fā)現實例最近一次接收pong消息的時間大于配置項cluster-node-timeout的一半,
便會立即對其發(fā)送ping消息,如果網絡堵塞的情況下,就會導致超時的實例變多,進而
使消息交互變多。
PING消息發(fā)送數量 = 1 + 10 * 實例數,1是指單實例常規(guī)按照每 1 秒發(fā)送一個 PING消息
10 是指每 1 秒內實例會執(zhí)行10 次檢查,每次檢查后會給 PONG 消息超時的實例發(fā)送消息,
假如一秒內的10次檢查共發(fā)現10臺實例pong消息超時,那么每秒得發(fā)送101次ping消息,
每個12k,共約占1.2mb/s的帶寬,這還是只是單實例,10臺便是12mb/s的帶寬占用
如何降低通信開銷
配置項 cluster-node-timeout 定義了集群實例被判斷為故障的心跳超時時間,默認
是 15秒。如果cluster-node-timeout 值比較小,那么,在大規(guī)模集群中,就會比較頻繁地出
現PONG 消息接收超時的情況,如果值比較大,便會導致實例故障被發(fā)現的時間延長,進而
導致實例恢復的時間變長,影響到集群的吞吐量。具體根據系統場景和集群的大小設置
cluster-node-timeout 的大小