1. Redis客户端和服务端通信协议
Redis客户端使用RESP(Redis Serialization Protocol)协议与Redis的服务器端进行通信,底层是基于TCP网络通信。RESP的优点:
RESP支持数据类型包括:简单字符串(Simple Strings),错误(Errors),整数(Integers),批量字符串(Bulk String)和数组(Arrays)。
- 简单字符串,回复的第一个字节是“+”
- 错误,回复的第一个字节是“ - ”
- 整数,回复的第一个字节是“:”
- 批量字符串,回复的第一个字节是“$”
- 数组,回复的第一个字节是“ *”
客户端将命令作为Bulk Strings的RESP数组发送到Redis服务器,服务器根据命令实现回复一种RESP类型。在RESP中,某些数据的类型取决于第一个字节,协议的不同部分始终以“\ r \ n”(CRLF)结束。
*<number of arguments> CR LF
$<number of bytes of argument 1> CR LF
<argument data> CR LF
...
$<number of bytes of argument N> CR LF
<argument data> CR LF
比如:发送命令 set key1 value1,底层抓包得到的二进制请求是:
*3 $3 set $4 key1 $6 value1
2. redis cluster 集群通信协议Gossip
redis集群采用去中心化设计,通过?Gossip协议保证最终一致性。Gossip 算法又被称为反熵(Anti-Entropy),最早是在 1987 年发表在 ACM 上的论文 《Epidemic Algorithms for Replicated Database Maintenance》中被提出,特点是:在一个有界网络中,每个节点都随机地与其它节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。
Gossip的特点
- 扩展性:允许节点的任意增加和减少,新增加的节点的状态最终会与其他节点一致;
- 容错:任何节点的宕机和重启都不会影响 Gossip 消息的传播,Gossip 协议具有天然的分布式系统容错特性。
- 去中心化:Gossip协议不要求任何中心节点,所有节点都可以是对等的,任何一个节点无需知道整个网络状况,只要网络是连通的,任意一个节点就可以把消息散播到全网。
- 一致性收敛:Gossip 协议系统状态的不一致可以在很快的时间内收敛到一致,消息传播速度达到了 logN。
- 简单性:Gossip 协议的过程极其简单,实现起来几乎没有太多复杂性。
Gossip 的缺陷
- 消息的延迟:Gossip 协议中,节点只会随机向少数几个节点发送消息,消息最终是通过多个轮次的散播而到达全网的,因此会造成不可避免的消息延迟。不适合用在对实时性要求较高的场景下。
- 消息冗余:Gossip 协议规定,节点会定期随机选择周围节点发送消息,而收到消息的节点也会重复该步骤,因此不可避免的存在消息重复发送给同一节点,造成了消息的冗余,同时也增加了收到消息的节点的处理压力。冗余通信会对网路带宽、CUP 资源造成很大的负载,而这些负载又受限于通信频率,该频率又影响着算法收敛的速度。
2.1 Redis cluster中gossip通信
Redis Cluster 中的每个Redis master实例监听两个 TCP 端口,6379(默认)用于服务客户端查询,16379(默认服务端口+10000)用于集群内部通信。集群中节点通信方式如下:
- 每个节点在固定周期内通过特定规则选择几个节点发送 Ping 消息;
- 接收到 Ping 消息后用Pong 消息作为响应。
Redis cluster中消息的种类:
|