Redis的通信协议

167 阅读4分钟

1.1、客户端和服务端之间

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)结束。

1.2、集群之间

Redis集群采用去中心化设计,通过 Gossip协议保证最终一致性。Gossip 算法又被称为反熵(Anti-Entropy),最早是在 1987 年发表在 ACM 上的论文 《Epidemic Algorithms for Replicated Database Maintenance》中被提出,特点是:在一个有界网络中,每个节点都随机地与其它节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。

1.2.1、Gossip协议介绍

扩展性:允许节点的任意增加和减少,新增加的节点的状态最终会与其他节点一致;
容错:任何节点的宕机和重启都不会影响 Gossip 消息的传播,Gossip 协议具有天然的分布式系统容错特性。
去中心化:Gossip协议不要求任何中心节点,所有节点都可以是对等的,任何一个节点无需知道整个网络状况,只要网络是连通的,任意一个节点就可以把消息散播到全网。
一致性收敛:Gossip 协议系统状态的不一致可以在很快的时间内收敛到一致,消息传播速度达到了 logN。
简单性:Gossip 协议的过程极其简单,实现起来几乎没有太多复杂性。

1.2.2、Gossip的缺陷

消息的延迟:Gossip 协议中,节点只会随机向少数几个节点发送消息,消息最终是通过多个轮次的散播而到达全网的,因此会造成不可避免的消息延迟。不适合用在对实时性要求较高的场景下。
消息冗余:Gossip 协议规定,节点会定期随机选择周围节点发送消息,而收到消息的节点也会重复该步骤,因此不可避免的存在消息重复发送给同一节点,造成了消息的冗余,同时也增加了收到消息的节点的处理压力。冗余通信会对网路带宽、CUP 资源造成很大的负载,而这些负载又受限于通信频率,该频率又影响着算法收敛的速度。

1.2.3、Redis cluster中Gossip通信

图片.png Redis Cluster是Redis的分布式集群解决方案,在 3.0 版本正式推出。Redis Cluster中的每个Redis master实例监听两个TCP端口,6379(默认)用于服务客户端查询,16379(默认服务端口+10000)用于集群内部通信。集群中节点通信方式如下:

每个节点在固定周期内通过特定规则选择几个节点发送 Ping 消息;
接收到 Ping 消息后用Pong 消息作为响应。

Redis cluster中消息的种类:

Meet消息:用于通知新节点加入。消息发送者通知接收者加入到当前集群,Meet 消息通信正常完成后,接收节点会加入到集群中并进行周期性的 Ping、Pong 消息交换;
Ping 消息:集群内交换最频繁的消息,集群内每个节点每秒向多个其它节点发送 Ping 消息,用于检测节点是否在线和交换彼此状态信息。Ping 消息发送封装了自身节点和部分其它节点的状态数据;
Pong 消息:当接收到 Ping、Meet 消息时,作为响应消息回复给发送方确认消息正常通信。Pong 消息内部封装了自身状态数据。节点也可以向集群内广播自身的 Pong 消息来通知整个集群对自身状态进行更新;
Fail 消息:当节点判定集群内另一个节点下线时,会向集群内广播一个 Fail 消息,其他节点接收到 Fail 消息之后把对应节点更新为下线状态。