前言
因为之前线上redis集群主从切换,client端未感知,导致往从库写数据报错,所以学习并整理了redis集群相关知识点。
主从复制
主从复制,是只从一台redis服务器的数据,复制到其他的一台或者多台redis服务器上。
前者为主节点(master),后者为从节点(slave)。
数据的复制只能从主节点到从节点。
主从复制主要起到以下几个作用:
- 数据冗余:实现了数据的热备份
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速恢复。
- 负载均衡:主节点提供写服务,从节点提供读服务,从而达到负载均衡的作用,常用于读多写少的功能,能有效提高服务器的并发量。
- 高可用基础:作为哨兵和集群的基础,为redis的高可用提供基础。
如下图,即为主从复制的整个过程:
主从复制的注意点:
- 1.延迟与不一致:repl-disable-tcp-nodelay no/yes ,当配置为yes时,TCP会对包进行合并从而减少带宽并降低频率,从节点数据延迟增加,一致性变差。
- 2.数据过期问题:在redis 3.2之前,从节点过期数据需要主节点来进行删除,当处于惰性删除时,从节点会获取到已经过期的数据,将redis升级到3.2之后即可解决。
- 3.故障转移:由于没有哨兵等机制,主从节点如果出现问题而发生更改时,需要修改程序或者另外写程序进行自动切换。
- 4.因为主从复制需要从节点发送指令到master,如果从节点过多,会导致主节点繁忙从而影响正常业务。
哨兵模式
在主从复制的基础上,引入了哨兵模式,提供了高可用解决方案,可以在没有人工干预的情况下实现故障恢复能力。
哨兵是一个独立的进程,监控各个节点的监控状态。
客户端通过连接sentinel来获取对应redis的主从节点。
哨兵模式主要起到以下几个作用:
- 1.监控:哨兵会不断检查主节点和从节点是否运作正常。
- 2.自动故障转移:当主节点无法正常工作时,哨兵会开始自动故障转移操作,将从节点选举为主节点,并让其他从节点改为复制新的主节点。
- 3.配置提供者:客户端初始化时,通过连接哨兵来获取当前redis服务的主节点地址。
- 4.通知:哨兵可以将各节点的状态发送给客户端。
扩展:我们公司通过对redis的扩展,一组sentinel里面连接了多个master,对key通过一致性hash来获取对应的分片,从而实现负载均衡。
sentinel常用配置:
- sentinel down-after-milliseconds <master-name> <milliseconds>
指定主节点应答哨兵sentinel的最大时间间隔,超过这个时间,哨兵主观上认为主节点下线(即主观下线
),默认30秒 - sentinel monitor <master-name> <ip> <redis-port> <quorum>
哨兵sentinel监控的redis主节点,其中quorum
指指定个数的sentinel认为master不可达,则认为主节点客观下线
。 - sentinel parallel-syncs <master-name> <numslaves>
指定了在发生failover主备切换时,最多可以有多少个slave同时对新的master进行同步。这个数字越小,完成failover所需的时间就越长;反之,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为1,来保证每次只有一个slave,处于不能处理命令请求的状态。 - sentinel known-sentinel
指定主节点所连接的sentinel节点信息
sentinel常见命令:
- sentinel is-master-down-by-addr
当主节点主观下线
时,向其他sentinel节点询问对该节点的状态判断,如果超过quorum
个数的节点判定不可达,则判断该主节点为客观下线
- SENTINEL masters / SENTINEL master <master_name>/SENTINEL slaves <master_name>
显示所有主节点 / 显示指定主节点 / 显示主节点的所有从节点状态 - SENTINEL get-master-addr-by-name <master_name>
返回主节点的IP和端口号(如果在进行failover
或者已经完成,则显示被提升为主节点的从节点信息) - SENTINEL reset <pattern>
重置名字匹配该 正则表达式 的所有的 主节点 的状态信息,清除它之前的 状态信息,以及 从节点 的信息,并自动重新发现。 - SENTINEL failover <master_name>
强制当前 Sentinel 节点执行 failover,并且不需要得到其他 Sentinel 节点的同意。但是 failover 后会将 最新的配置 发送给其他 Sentinel 节点。 - info
info信息下会有当前sentinel的各种信息:- 1.master:当前sentinel监听的主节点的状态
- SENTINEL REMOVE <name>
用来移除指定的主节点:主节点不再被监控,并且将被从Sentinel的内部状态中被完全移除,所以不会被SENTINEL masters列出。
发布/订阅消息列表
- +reset-master <instance details> --- 主节点被重置。
- +slave <instance details> --- 一个新的从节点被发现和关联。
- +failover-state-reconf-slaves <instance details> --- 故障转移状态被转换为reconf-slaves状态。
- +failover-detected <instance details> --- 另一个Sentinel开始了故障转移或者其他的外部实体被发现(一个关联的从节点变为主节点)。
- +slave-reconf-sent <instance details> --- 为了给新的从节点重新配置,sentinel 中的leader发送SLAVEOF命令到这个实例。
- +slave-reconf-inprog <instance details> --从节点被重新配置展示一个主节点的从节点,但是同步过程尚未完成。
- +slave-reconf-done <instance details> --- 从节点现在和主节点是同步的。
-dup-sentinel <instance details> --指定的主节点,一个或者多个sentinels被 移除,因为是重复的。 - +sentinel <instance details> --- 这个主节点的一个新的sentinel被发现和关联。
- +sdown <instance details> --- 指定的实例现在处于主观下线状态。
- -sdown <instance details> --- 指定的实例不再处于主观下线状态。
- +odown <instance details> --- 指定的实例现在处于客观下线状态。
- -odown <instance details> --- 指定的实例现在不处于客观下线状态。
- +new-epoch <instance details> --- 当前时间被更新。
- +try-failover <instance details> --- 准备新的故障转移,等待大多数的选举。
- +elected-leader <instance details> --- 赢得了选举,开始故障转移。
- +failover-state-select-slave <instance details> --- 新的故障转移状态是select-- slave:我们 正在寻找合适提升为主节点的从节点。
- no-good-slave <instance details> --- 没有合适进行提升的从节点。一般会在稍后重试,但是这或许会改变并且终止故障转移。
- selected-slave <instance details> --- 我们找到了指定的从节点来进行提升。
- failover-state-send-slaveof-noone <instance details> --- 我们尝试重新配置这个提升后的主节点,等待它切换。
- failover-end-for-timeout <instance details> --- 故障转移由于超时而停止,无论如何从节点最后被配置为复制新的主节点。
- failover-end <instance details> --- 故障转移由于成功而停止,所有的从节点被配置为复制新的主节点。
- switch-master <master name> <oldip> <oldport> <newip> <newport> --- 配置改变后,主节点新的IP和地址都是指定的。这是大多数外部用户感兴趣的消息。
- +tilt --- 进入Tilt模式。
- -tilt --- 退出Tilt模式。
呼应前言,之前线上出现,手动failover的时候,客户端没有感知主从切换,导致始终往老的主节点写数据,此时老的主节点已经变成从节点,写入报错。
经排查,是因为线上redis配置了7个sentinel,其中4个不可用,而quorum为2,这导致,当2个sentinel节点同意主节点不可用,尝试开始故障转移,但是没有至少4个sentinel节点授权并开始,所以sentinel就不会开始故障转移,也就不会publish相关消息,导致客户端不感知。
集群模式
待完善