参考地址: 《redis三种模式对比》
Redis 集群模式有三种:主从模式(Redis 2.8 版本之前)、哨兵模式(Redis 3.0 之前)、集群模式(Redis 3.0 之后)。
同 Mysql 主从复制的原因一样,Redis 虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis 支持主从复制,Redis 的主从结构可以采用一主多从,或者级联结构,Redis 主从复制可以根据是否是全量分为全量同步和增量同步。下图为级联结构。
Redis 全量复制一般发生在 Slave 初始化阶段,这是 Slave 需要将 Master 上的所有数据都复制一份。具体步骤如下:
哨兵 (Sentinal) 的作用是监控 Redis 服务器的状态,可以实现在 Master 节点下线时,将其他 Slave 节点升级为 Master 节点的功能。多个哨兵可以监控同一个 Redis 节点,哨兵与哨兵之间也可以相互监视。
哨兵进程启动后,会读取配置文件内容,查找到 Master 服务器的 IP 与端口,与 Master 服务器建立两条连接。此外,只要给哨兵提供多个 Master 服务器的信息,就能实现一个哨兵监控多个 Master 服务器。
与 Master 服务器建立连接后,哨兵会按照一定频率执行三个操作:
认为 Master 节点客观下线后,故障恢复的操作需要一个领头的哨兵执行。选举采用 RAFT 算法:
选出领头哨兵后,领头者开始对进行故障恢复,从出现故障的 master 的从数据库中挑选一个来当选新的 master,选择规则如下:
挑选出需要继任的 slave 后,领头哨兵向该节点发送命令,使其升格为 master,然后再向其他 slave 发送命令接受新的 master,最后更新数据。此外,已经停止的旧的 master 更新为新的 master 的从数据库,使其恢复服务后以 slave 的身份继续运行。
优点:
缺点:
Redis 集群模式如下图所示,每一个蓝色的圈都代表着一个 redis 的服务器节点,它们任何两个节点之间都是相互连通的,每一个节点都存有这个集群所有主节点以及从节点的信息。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
一般集群建议搭建三主三从架构,三主提供服务,三从提供备份功能。
Redis 节点之间通过互相的 ping-pong 判断是否节点可以连接上。如果有一半以上的节点去 ping 一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。这就是 Redis 的投票机制,具体原理如下图所示:
投票过程是集群中所有 master 参与,如果半数以上 master 节点与某个 master 节点通信超时 (cluster-node-timeout),认为该 master 节点挂掉。
整个集群不可用的判断条件:
在集群模式下,通过 cluster info 命令可以查看集群的信息,包括每个 Redis 节点的 ID、IP+端口、身份 (master/slave)、连接数量、分配插槽 (slot) 信息。
以执行命令 set abc 123
为例,Redis 将数据存到集群中的步骤如下:
set abc 123
,某个 Redis 节点接收到命令;key(“abc”)
计算出 slot 值,根据 slot 值找到对应的 Redis 节点; 注:插槽与 key 的关系: key 的有效部分使用 CRC16 算法,计算出 Hash 值,然后对 16384 取余获得 slot 值。有效部分指:
key={hello}_grq
中的 “hello”;Redis 集群提供了 16384 个 slot,通过 Ruby 脚本 redis-trib.rb 实现 slot 平均分配给 N 个 master 节点。如果有一部分 slot 没有指定到节点,那么分配在这部分 slot 上的 key 值将不能使用。
但如果向集群中加入新的 master 节点,或者将某个 master 节点删除,则需要通过执行 redis-trib.rb 脚本实现 slot 的重分配。
新增节点后,实现 slot 重分配的步骤如下:
redis-trib.rb add-node {待添加节点 IP + 端口}
; redis-trib reshard + {待分配目的节点}
脚本命令,执行重分配操作;命令执行过程中,输入要移动的 slot 数、待分配目的节点 ID,以及从哪里分配节点(如果写 “all”,则将所有 master 节点的部分 slot 共同分配给该节点);删除节点实现 slot 重分配步骤如下:
redis-trib.rb del-node {待删除节点 IP + 端口} {待删除节点 ID}
;