概念
Redis集群是由多个redis实例组成的一个分布式系统,数据按照slot存储分布在多个redis实例上,通过Gossip协议实现节点之间的通信。
功能特点
1)所有节点相互连接
2)集群通过集群总线通信
3)集群节点与节点之间通过二进制协议通信
4)客户端和集群节点之间依然是通过文本协议通信
5)集群节点挂掉会自动故障迁移
6)可以扩缩容节点
新节点是如何加入集群的
- 当新加入节点后,管理员向节点A发送CLUSTER MEET ip port命令
- 节点A为节点B创建一个clusterNode结构,并将该结构写入自己的字典里
- 节点A命令提供的地址和端口,向节点B发送发送一条MEET消息
- B收到A的信息后,会在自己的字典里为A创建一个结构,并将这个结构添加到自己的字典里。
- B接着向A返回一条PONG消息,A收到这条消息后就知道B已经成功接收了自己的MEET消息了
- 之后A向B发送一条PING消息
- B收到A的PING消息后,知道A已经收到自己的PONG消息,握手完成。
- 之后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集群创建
- 首先创建3master、3slave的集群
- 通过add-node 新节点套接字 任意旧节点套接字来添加一个新的master节点;通过add-node --slave 新节点套接字 某master节点套接字 来给某master添加slave
Gossip通信方式
通信方式
- push:A将(key, value,version)推送给B,B更新A比自己新的数据
- pull:A将(key, version)推送给B,B返回比A新的数据,A再更新本地
- push/pull:在pull基础上再增加A push 比B新的数据给B