Redis集群模式通信成本影響因素
一、通信開銷影響因素
節(jié)點數(shù)量
每秒從本地實例列表選擇5個節(jié)點,在這5個節(jié)點中選擇最久沒有通信的實例,向該實例發(fā)送PING消息。
即:定時發(fā)送PING消息的節(jié)點數(shù)量=5。
避免一些實例節(jié)點一直選不到,會有一個定時任務掃描兜底措施。
集群內部每秒10次的固定頻率掃描本地緩存節(jié)點列表,也就是每100ms一次。
如果節(jié)點:PONG更新時間node.pong_received>(cluster-node-timeout/2)立即向該節(jié)點發(fā)送PING消息,假設該數(shù)量為N。
即:兜底發(fā)送的節(jié)點數(shù)量=10 * N。
通過調大cluster_node_timeout可以減少通信的節(jié)點數(shù)量,例如:從15秒調整到30秒。
但是,cluster_node_timeout過大會影響故障發(fā)現(xiàn)的時間和新節(jié)點發(fā)現(xiàn)的時間。
消息大小
一次通信包含消息頭和消息體。
消息頭:PING消息頭相對固定,主要占用的發(fā)送節(jié)點負責的槽位(myslots[CLUSTER_SLOTS/8])占用2KB。
消息體:會攜帶一定數(shù)量的其他節(jié)點信息,默認包含集群總節(jié)點數(shù)的1/10,最少包含集群的3個節(jié)點,最多包含集群總節(jié)點數(shù)-2。
消息體clusterMsgDataGossip各個字段字節(jié)大小,共計104個字節(jié)。
屬性 | 大小 |
char nodename[CLUSTER_NAMELEN] | 40字節(jié) |
uint32_t ping_sent | 4字節(jié) |
uint32_t pong_received | 4字節(jié) |
char ip[NET_IP_STR_LEN] | 46字節(jié) |
uint16_t port | 2字節(jié) |
uint16_t cport | 2字節(jié) |
uint16_t flags | 2字節(jié) |
uint16_t pport | 保留字段 |
uint16_t notused1 | 4字節(jié) |
合計 | 104字節(jié) |
200個節(jié)點的redis集群,一次通信成本:2KB的消息頭+2KB的消息體(20*104)= 4KB,一來一回8KB。
攜帶消息體的大小與集群規(guī)模相關,規(guī)模越大消息體越大,通信成本越高。
達到一定程度后整體集群性能會下降,Redis Cluster官方建議最大規(guī)模1000個實例,實際中通常不會超過500個實例。
二、擴縮容與槽位遷移
節(jié)點擴縮容本質上是槽在節(jié)點之間的遷移。
節(jié)點擴容后,需要將原有節(jié)點上的槽遷移到新節(jié)點。
如下圖所示,當集群中加入節(jié)點4時,將節(jié)點1的Slo01,節(jié)點2的Slot04,節(jié)點3的Slot07遷移給節(jié)點4以實現(xiàn)數(shù)據(jù)均衡。
節(jié)點縮容前,需要將待下線節(jié)點上的槽先遷移走。
如下圖所示,當集群中節(jié)點4下線,需要先將其擁有的槽位Slot01、Slot04、Slot07遷移走。
槽位遷移命令有:ADDSLOTS、DELSLOTS、FLUSHSLOTS、SETSLOT。
三、請求路由與重定向
數(shù)據(jù)存儲在槽里,槽分布在實例上,處理客戶端請求也是找對應槽的過程。
請求重定向
請求路由過程如下:
- @1 客戶端發(fā)送請求命令到集群任意節(jié)點
- @2 計算key對應的槽,計算公式:slot=CRC16(key)&16383
- @3 槽在本節(jié)點,執(zhí)行命令,每個實例維護自身負責的槽也維護其他實例負責的槽位
- @4 槽不在本節(jié)點,回復MOVE到其他節(jié)信息點
- @5 向目標節(jié)點發(fā)起請求
為了減少MOVE重定向的開銷,例如Jedis在客戶端實現(xiàn)時緩存了槽與節(jié)點的關系,減少通信的開銷。
然而也增加了客戶端的復雜性,客戶端會為集群中每個節(jié)點獨立的連接池,集群規(guī)模大時占用更多的本地緩存。
ASK重定向
如果訪問的槽正在做遷移,一部分數(shù)據(jù)在源節(jié)點,而另一部分已經遷移到目標節(jié)點,這個流程是如何的?
ASK重定向流程:
- @1 發(fā)送請求命令
- @2 計算key對應的槽
- @3 槽在本節(jié)點,數(shù)據(jù)也在,執(zhí)行命令
- @4 訪問的數(shù)據(jù)正在遷移,回復ASK信息含請求數(shù)據(jù)的目標節(jié)點
- @5 向目標節(jié)點發(fā)起ASKING請求、執(zhí)行命令獲取數(shù)據(jù)
ASK的重定向是臨時性的,客戶端(Jedis)收到回復不更新客戶端槽與節(jié)點映射,而MOVE的重定向會更新本地槽映射關系。