如果想保证系统的高可用,我们需要对mysql、redis等应用进行集群部署。这篇我们看看redis集群的使用。
主从复制 |
Redis集群分为主节点和从节点。复制的数据只能由主节点复制到从节点。如果我们执行读的操作,在主节点和从节点上获取皆可,如果执行写操作,只能写到主节点上,然后再由主节点复制到从节点上。
集群结构
Redis的集群结构可以为:一主一从,一主多从,树状主从。
复制过程
(1)从节点保存主节点的地址信息,包括ip和port。
(2)从节点内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该节点建立网络连接。
(3)连接建立成功后,从节点发送ping请求进行首次通信。
(4)权限认证。如果主节点设置了requirepass参数,则需要密码。
(5)同步数据集。当建立正常通信后,主节点会把持有的数据全部发送给从节点。有两种方式可选择:全量复制、部分复制。
(6)命令持续复制。当主节点有新的写入时,会将写命令发送给从节点,从而保证主从数据一致性。
复制方式
在刚才的第(5)步中也说到了这两种复制方式。
(1)全量复制
全量复制是将主节点的全部数据一次性发送给从节点,一般用于初次复制场景。
(2)部分复制
部分复制是补发丢失数据给从节点,一般用于处理在主从复制中因网络闪断等原因造成的数据丢失场景。从2.8版本以上才支持此功能。
遇到的问题与解决办法
(1)数据延迟
当我们将数据写到主节点上后,主节点将数据同步到从节点,同步的时间取决于网络带宽和命令阻塞情况,所以可能会存在延迟的情况。所以我们可以编写外部监控程序监听主从节点的复制偏移量,当延迟较大时触发报警或者通知客户端避免读取延迟过高的从节点。
(2)读到过期数据
redis中有过期策略,所以有些数据可能已经过期。其内部有两种过期数据删除策略:
- 惰性删除
主节点每次处理读命令时,都会检查键是否超时。如果超时则进行删除,然后再把删除命令发送给从节点。
- 定时删除
Redis主节点在内部定时任务会循环采样一定数量的键,当发现采样的键过期时,进行删除,然后再发送相关命令给从节点。
(3)从节点故障
我们需要在客户端维护可用从节点列表,一旦某个节点出现故障,立即切换到其他节点。
哨兵机制 |
Redis2.8版本不仅提供了部分复制的功能,也提供了哨兵机制。哨兵机制是干嘛的?在redis集群中,如果主节点出现故障不能提供服务了,需要选一个从节点晋升为主节点,同时还要通知应用方更新主节点地址。这个机制就是哨兵机制。
不仅redis中有哨兵机制,zookeeper中也有。
部署架构
在redis架构中,有3种角色:主节点、从节点、sentinel(监控各数据节点)。
实现原理
(1)3个定时监控任务
每隔10s,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构。
每隔2s,每个Sentinel节点会发送对于主节点的判断以及当前Sentinel节点的信息。
每个1s,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测。
(2)主观下线和客观下线
主观下线:某一个Sentinel节点认为某个其它节点“死了”。
客观下线:大部分Sentinel节点都对主节点的下线做了同意的判定。
(3)领导者Sentinel节点选举
Sentinel节点之间也会做一个领导者选举的工作,选出一个Sentinel节点作为领导者进行故障转移的工作。其选举工作使用的是Raft算法。
(4)故障转移
领导者选举出的Sentinel节点负责故障转移。步骤大致为:
①在从节点中选出一个节点作为新的主节点
②Sentinel领导者节点对选出来的从节点执行slaveof no one命令,让其成为主节点
③Sentinel领导者向剩余的从节点发送命令,让它们成为新主节点的从节点
④Sentinel节点集合将原来的主节点更新为从节点,并对其进行关注,当其恢复后,命令它去复制新的主节点。
集群的搭建与使用 |
分区规则
Redis集群数据分区规则采用虚拟槽方式,所有的键映射到16384个槽中,每个节点负责一部分槽和相关数据,实现数据和请求的负载均衡。
搭建步骤
(1)准备节点
(2)节点握手
(3)分配槽
节点通信
集群内部节点通信采用Gossip协议彼此发送消息,消息类型分为:ping消息,pong消息,meet消息,fail消息等。
集群伸缩
集群伸缩就是在redis集群中添加或删除节点。其可以通过在节点之间移动槽和相关数据实现。
- 扩容
扩容时根据槽迁移计划把槽从源节点迁移到目标节点,源节点负责的槽变少从而达到扩容的目的。
- 收缩
收缩时如果下线的节点有负责的槽需要迁移到其它节点,通过cluster forget命令让集群内其它节点忘记被下线节点。
参考资料 |
《Redis开发与运维》