概念

Redis集群是由多个redis实例组成的一个分布式系统,数据按照slot存储分布在多个redis实例上,通过Gossip协议实现节点之间的通信。

功能特点

1)所有节点相互连接

2)集群通过集群总线通信

3)集群节点与节点之间通过二进制协议通信

4)客户端和集群节点之间依然是通过文本协议通信

5)集群节点挂掉会自动故障迁移

6)可以扩缩容节点

新节点是如何加入集群的

  1. 当新加入节点后,管理员向节点A发送CLUSTER MEET ip port命令
  2. 节点A为节点B创建一个clusterNode结构,并将该结构写入自己的字典里
  3. 节点A命令提供的地址和端口,向节点B发送发送一条MEET消息
  4. B收到A的信息后,会在自己的字典里为A创建一个结构,并将这个结构添加到自己的字典里。
  5. B接着向A返回一条PONG消息,A收到这条消息后就知道B已经成功接收了自己的MEET消息了
  6. 之后A向B发送一条PING消息
  7. B收到A的PING消息后,知道A已经收到自己的PONG消息,握手完成。
  8. 之后A会将B的信息传给集群中的其他节点,让其他节点也跟B握手,最终B会被集群中所有节点认识。

端口

每个redis节点至少需要开启两个端口

1)一个用于正常的给client提供服务,比如6379

2)一个用于集群总线,端口在1)加10000,比如13679

集群总线采用二进制协议,用于节点之间交换数据

Redis数据分布

Redis集群中有16384个哈希槽,通过对key的CRC16值取模来决定某个key到底该落在哪个槽上,集群中的节点均摊这16384个槽。

主从模式

每个节点都有master和slave两个节点,当某个master节点失效后,集群会将它的slave提升为新的master。

一致性保证

Redis的一致性保证可能会丢失一些操作,因为:

1)客户将消息写到master

2)master回复客户端ok

3)master将写操作广播给它的slave

所以可能导致消息的丢失

另外网络分区也可能导致消息的丢失,假设有3master 3slave组成的集群,本来都在一个分区中,突然网络分区发生,导致其中2master与3slave在同一个分区,另外一个masterA在另一个分区,这时客户向这个masterA写入消息,而5个节点的那个分区认为隔离开来的这个master挂了,就把对应的slave A1提升为master,最后导致A需要从A1同步数据。

Redis集群创建

  1. 首先创建3master、3slave的集群
  2. 通过add-node 新节点套接字  任意旧节点套接字来添加一个新的master节点;通过add-node --slave  新节点套接字  某master节点套接字 来给某master添加slave

Gossip通信方式

通信方式

  1. push:A将(key, value,version)推送给B,B更新A比自己新的数据
  2. pull:A将(key, version)推送给B,B返回比A新的数据,A再更新本地
  3. push/pull:在pull基础上再增加A push 比B新的数据给B