前面章节搭建了Redis【主-从】架构和【主-从】+ 哨兵架构,已可满足部分企业场景应用,但都有其对应的弊端,本章节将讲解更优生产架构:Redis集群架构。不仅包含哨兵架构的自动选举功能,还能降低主从架构下主节点的单节点压力,且更易于拓展。
1,集群架构原理
Redis集群架构的架构图如下:
Redis集群是由多个【主-从】架构合并组成的分布式服务集群,将每个【主-从】设置为集群节点,使得集群架构具有复制、高可用、数据分片的特性。
数据分片原理
Redis集群的数据分片,是指将数据分散存储在多个节点上,以减轻单节点读写压力,提高数据存储能量条。Redis集群将数据存储位置为划分为16834个slots(槽位),编号是:0~16383。16384个槽位是官方根据性能评估出的最好结果,便于拓展,理论上可以更多。
每个集群中的节点【主-从】负责一部分槽位,数据存储时,通过对key做CRC16算法,结果再对16384取模,得出key的槽位值(HASH_SLOT = CRC16(key) mod 16384),再将【K-V】数据存储到对应槽位的节点上。如上图:集群共有三个节点,则第一节点master槽位:0~5460,第二个节点maseter槽位:5461~10922,第三个节点maseter槽位:10923~16383。当客户端连接集群时,会将集群各节点槽位信息缓存至客户端本地,提升定位节点效率。
跳转重定向:当集群节点数量发生变化,节点槽位也会发生变化,若客户端对错误节点发送操作指令时,节点会将该key对应槽位与自身负责槽位作对比,不在自身负责槽位范围内,节点会向客户端发送跳转指令,并携带目标节点地址。客户端收到指令后将向正确节点重发指令,并更新本地槽位缓存。
集群选举原理
集群里每个【主-从】架构中的Redis节点与其他【主-从】的节点相互之间都有通讯,通讯机制采用的是gossip协议,保证通讯结果的最终一致性。需注意:当主节点宕机后,从节点的选举,只有从节点与其他【主-从】架构的“主”节点的通讯结果有效。选举步骤如下图:
1,主1宕机后,等待主2、主3与主1的下次通讯,确保主2、主3通过通讯失效判定主1宕机;
2,从1-A、从1-B标记故障转移请求次数(currentEpoch = 1),然后向主2、主3发送故障转移请求,即请求自己升级为新的主节点(主4),如从1-A的1,2请求,从1-B的3,4请求;
3,主2、主3收到升级请求后判断请求的合法性,合法后,只回复最先收到的升级请求,后来的升级请求不做回复;
4,当从1-A 或 从1-B收到超过主节点半数的同意升级请求的返回后,则升级为新的主节点。即如果从1-A收到主2、主3的同意返回,则从1-A升级为主节点(同理,从1-B升级为主节点)。
注意:上图中总主节点数为3,如果从1-A、从1-B收到的同意请求返回数相同,即各自收到一条同意,则重新发起一次选举,即重复234步(故障转移请求次数 +1,发送请求,等待回复,判断结果数量,升级主节点)
根据上述步骤可知,选举机制中的【过半判断】取决于 集群中主节点数量,如果只有两个主节点,主1宕机后,从1-A、从1-B收到的ACK数量永远只能等于主节点总数量的一般,则永远无法升级为主节点,主1所在服务将不可用。故集群中Redis主节点至少需要三个,才可满足宕机选举的过半机制。
2,Redis集群搭建
根据前文选举原理可知,Redis集群至少需要三个节点,本章则搭建三个【主-从】节点的集群,共6个Redis服务。
1,添加Redis节点配置文件
复制六份redis.conf文件,分别为redis-8000.conf, redis-8001.conf, redis-8002.conf, redis-8003.conf, redis-8004.conf, redis-8005.conf
cp config/master-slave/redis-6379.conf config/cluster/redis-8000.conf
2,修改配置文件
以redis-8000.conf举例,其余5个配置文件只需修改内容里的端口即可
bind 0.0.0.0 // 不限IP
port 8000protected-mode no // 关闭IP保护模式,通过密码访问
daemonize yes // 后台运行
pidfile /var/run/redis_8000.pid
logfile "/opt/mydata/redis-5.0.0/logs/redis-cluster-8000.log"
dir /opt/mydata/redis-5.0.0/data/cluster/8000/ // 数据存储位
masterauth 123456 // 集群节点间访问密码
requirepass 123456 // Redis服务端访问密码// 持久化配置
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec// 集群配置
cluster-enabled yes // 开启使用集群架构
cluster-config-file nodes-8000.conf // 记录集群节点信息文件
cluster-node-timeout 15000 //
3,启动6个节点
src/redis-server config/cluster/redis-8000.conf
4,配置主从和集群
此时6个节点还没有主从关系,也没有建立起集群间的通讯,通过如下命令建立:
src/redis-cli -a 123456 --cluster create 127.0.0.1:8000 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 --cluster-replicas 1
// -a password: 连接服务端密码
// --cluster create: 创建集群命令。cluster create host1:port1...hostN:portN
// --cluster-replicas N: N表示为每个master创建几个slave.本案例设置为1,结构为一主一从,则6/2,共有三个【主-从】结构。如果N=2,结构为一主两从,则6/3,共两个一主两从的结构。即Redis会根据后面的主机与N做适配。
生产环境搭建时,至少需要三台Redis服务器,Redis会自动将主从非配在不同的机器上,以保证每个【主-从】架构至少有一个节点可正常访问。
5,验证集群
5.1,连接任意一个客户端:
src/redis-cli -a 123456 -c -h 127.0.0.1 -p 8000
// -a 访问服务端密码// -c 集群模式,访问的是集群的节点
// -h 指定host
// -p 指定端口
5.2,验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)
5.3,数据操作验证
5.4,关闭集群需逐个进行关闭,使用命令:
src/redis‐cli ‐a 123456 ‐c ‐h 127.0.0.1 ‐p 8000 shutdown