Redis Cluster
redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性,不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展。

redis下载安装
参考<Redis使用>
Redis集群搭建
redis集群需要至少要三个master节点,并且给每个master再搭建一个slave节点,总共至少6个redis节点。
创建好目录结构,指定数据文件存放位置,为每个节点创建独立的数据存放文件夹。
$mkdir -p /usr/local/redis-cluster
$mkdir 8001
把之前的redis.conf配置文件copy到8001下,修改如下内容:
daemonize yes
port 8001 (分别对每个机器的端口号进行设置)
dir /usr/local/redis-cluster/8001/ (指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)
cluster-enabled yes ( 启动集群模式)
cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x最好和port对应上)
cluster-node-timeout 5000
# bind 127.0.0.1 (去掉bind绑定访问ip信息)
protected-mode no (关闭保护模式)
appendonly yes
#设置密码
requirepass cvccy (设置redis访问密码)
masterauth cvccy (设置集群节点间访问密码,跟上面一致)
把修改后的配置文件分别copy到所有节点,修改port等信息。
分别启动6个redis实例,然后检查是否启动成功
$/usr/local/redis/src/redis-server /usr/local/redis-cluster/800*/redis.conf
#查看是否启动成功
$ps -ef | grep redis
用redis-cli创建整个redis集群
- --cluster-replicas 1:每个创建的主服务器节点创建一个从服务器节点
- 执行这条命令需要确认redis实例之间要能相互访问,需要打开redis服务端口和集群节点gossip通信端口16379=10000+port(默认是在redis端口号上加1W)
- 关闭防火墙
- systemctl stop firewalld # 临时关闭防火墙
- systemctl disable firewalld # 禁止开机启动
$src/redis-cli -a cvccy --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
验证集群:
- 连接任意一个客户端:./redis-cli -c -h -p (-a访问服务端密码,-c表示集群模式,指定ip地址和端口号)
- 进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)
- 关闭集群则需要逐个进行关闭
src/redis-cli -a 123++abc -c -p 8001
集群原理
slots
Redis Cluster 将所有的数据key通过Hash函数划分为16384个slots,每个Master负责一部分,当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样要查找某个key时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。
slots定位算法
Cluster默认会对key使用crc16运算得到hash值,再对16384取模得到具体slots信息。HASH_SLOT = CRC16(key) mod 16384
跳转定位
节点收到不属于自己的key信息后,会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,客户端收到指令后除了跳转到正确的节点上去操作,会同步更新纠正本地的槽位映射表缓存。
通信机制
Redis Cluster节点通过Gossip协议通信,元数据维护方式有集中式和gossip通信方式。
集中式
元数据的更新和读取,时效性非常好
- 快速感知:元数据出现变更立即就会更新到集中式的存储中,其他节点读取的时候立即就可以立即感知到
- 存储压力:所有的元数据的更新压力全部集中在一个地方,可能导致元数据的存储压力。
gossip

gossip包含多种消息
- ping:节点之间频繁发送,包含自己的状态、维护的集群元数据,通过ping交换元数据
- pong:返回ping和meet,包含自己的状态和其他信息,也可以用于信息广播和更新
- fail:发现并通知其他节点,指定的节点宕机
Redis集群选举原理分析
当slave发现自己的master变为FAIL状态时,便尝试进行Failover,多个slave竞争成为master节点的过程:
- slave发现自己的master变为FAIL
- 将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST 信息
- 其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
- 尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
- slave收到超过半数master的ack后变成新Master(这里解释了集群为什么至少需要三个主节点,如果只有两个,当其中一个挂了,只剩一个主节点是不能选举成功的)
- slave广播Pong消息通知其他集群节点。
从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票
• 延迟计算公式:DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
• SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。理论上,持有最新数据的slave将会首先发起选举。
Cluster数量
- 至少需要三个master节点,并且推荐节点数为奇数
新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中一个挂了,是达不到选举新master的条件的。奇数个master节点可以在满足选举该条件的基础上节省一个节点。
集群批量操作
集群只支持所有key落在同一slot的情况,可以在key的前面加上{XX},这样参数数据分片hash计算的只会是大括号里的值。
mset {user1}:name zhuge {user1}:age 18

浙公网安备 33010602011771号