聊聊 Redis 集群 Gosisp 协议与节点通信
为了应对流量并发瓶颈,协信以及方便数据迁移与扩容,议节数据分片方式是点通常用的解决方式。
Kafka的聊聊分区(partition)、RocketMQ的协信队列(Queue)、Elasticsearch的议节主分片/副本(shard)、数据库的点通分库分表等,均采用数据分片思想应对高并发流量。聊聊
Redis的协信集群模式也不例外,采用虚拟槽slot实现数据分片。议节
Redis的点通槽位范围0~16383,共16384个槽位。聊聊
Redis Cluster中每个节点负责一部分槽数量,协信分配算法:slot=CRC16(key)&16383。议节
槽位分配与选择示意图如下:

1、Gosisp协议类型
节点通信使用Gosisp协议,消息类型有:ping消息、pong消息、meet消息、b2b信息网fail消息。

通信端口=节点端口+10000。
每个节点周期性的选择几个节点发送ping消息。
2.消息头格式
消息头的结构在clusterMsg中,具体属性如下:
字段
说明
简述
char sig[4]
Signature "RCmb" (Redis Cluster message bus).
信号签名
uint32_t totlen
Total length of this message
消息长度
uint16_t ver
Protocol version, currently set to 1
协议版本
uint16_t port
TCP base port number
端口信息
uint16_t type
Message type
消息类型,ping、meet、pong等
uint16_t count
Only used for some kind of messages
消息体包含的节点数量
uint64_t currentEpoch
The epoch accordingly to the sending node
发送节点的纪元(epoch)配置
uint64_t configEpoch
The config epoch if its a master,
or the last epoch advertised by its master if it is a slave
主从节点中,主节点的纪元配置
uint64_t offset
Master replication offset if node is a master
or processed replication offset if node is a slave
复制偏移量
char sender[CLUSTER_NAMELEN]
Name of the sender node
发送节点的nodeId信息
unsigned char myslots[CLUSTER_SLOTS/8]
myslots info
发送节点负责的槽位信息
char slaveof[CLUSTER_NAMELEN]
从节点的nodeId信息
char myip[NET_IP_STR_LEN]
Sender IP, if not all zeroed
发送者IP
uint16_t extensions
Number of extensions sent along with this packet
扩展信息
char notused1[30]
30 bytes reserved for future usage
保留30个字节扩展供未来使用
uint16_t pport
Sender TCP plaintext port, if base port is TLS
如果基础端口为TLS,WordPress模板TCP的明文端口
uint16_t cport
Sender TCP cluster bus port
发送者TCP集群总线端口
uint16_t flags
Sender node flags
发送节点标识,区分主从以及是否下线
unsigned char state
Cluster state from the POV of the sender
发送者角度的集群状态
unsigned char mflags[3]
Message flags: CLUSTERMSG_FLAG[012]_...
消息标识
union clusterMsgData data
消息体正文
3.消息体格式
消息体clusterMsgData结构如下:
复制union clusterMsgData { /* PING, MEET and PONG */ struct { /* Array of N clusterMsgDataGossip structures */ clusterMsgDataGossip gossip[1]; /* Extension data that can optionally be sent for ping/meet/pong * messages. We cant explicitly define them here though, since * the gossip array isnt the real length of the gossip data. */ } ping; /* FAIL */ struct { clusterMsgDataFail about; } fail; /* PUBLISH */ struct { clusterMsgDataPublish msg; } publish; /* UPDATE */ struct { clusterMsgDataUpdate nodecfg; } update; /* MODULE */ struct { clusterMsgModule msg; } module;};1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.备注:clusterMsgDataGossip:PING, MEET and PONG采用的消息结构体,详细如下。
复制typedef struct { char nodename[CLUSTER_NAMELEN]; uint32_t ping_sent; uint32_t pong_received; char ip[NET_IP_STR_LEN]; /* IP address last time it was seen */ uint16_t port; /* base port last time it was seen */ uint16_t cport; /* cluster port last time it was seen */ uint16_t flags; /* node->flags copy */ uint16_t pport; /* plaintext-port, when base port is TLS */ uint16_t notused1;} clusterMsgDataGossip;1.2.3.4.5.6.7.8.9.10.11. nodename:节点NodeIdping_sent:最后一次向该节点发送ping消息时间pong_received:最后一次接受该节点pong消息时间ip/port/cport/flags/pport:IP端口以及节点标识三、节点选择与通信流程1.节点通信流程
两个节点之间发送MEET/PING消息,回复PONG消息的流程如下。

2.通信节点选择
Gosisp协议PING/PONG通信时,具体选择哪个节点发起通信?
每秒从本地实例列表选择5个节点,在这5个节点中选择最久没有通信的实例,向该实例发送PING消息。
避免一些实例节点一直选不到,会有一个定时任务扫描兜底措施。
集群内部每秒10次的固定频率扫描本地缓存节点列表,也就是每100ms一次。
如果节点:PONG更新时间>(cluster-node-timeout/2)立即向该节点发送PING消息。
cluster-node-timeout是判定实例故障的心跳超时时间,默认15秒。

本文地址:http://www.bzuk.cn/html/210f8299707.html
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。