摘要:Redis 在主从模式下会有许多问题须要思考,这里写了一些对于 redis 在多服务器下的一些问题剖析和总结。
Redis 单节点存在单点故障问题,为了解决单点问题,个别都须要对 redis 配置从节点,而后应用哨兵来监听主节点的存活状态,如果主节点挂掉,从节点能持续提供缓存性能。主从配置联合哨兵模式能解决单点故障问题,进步 redis 可用性。从节点仅提供读操作,主节点提供写操作。对于读多写少的情况,可给主节点配置多个从节点,从而进步响应效率。
主从复制过程:
- 从节点执行 slaveofmasterIP,保留主节点信息
- 从节点中的定时工作发现主节点信息,建设和主节点的 socket 连贯
- 从节点发送 Ping 信号,主节点返回 Pong,两边能相互通信
- 连贯建设后,主节点将所有数据发送给从节点(数据同步)
- 主节点把以后的数据同步给从节点后,便实现了复制的建设过程。接下来,主节点就会继续的把写命令发送给从节点,保障主从数据一致性。
Redis 的数据同步过程:
redis2.8 之前应用 syncrunId 同步命令,redis2.8 之后应用 psyncrunId 命令。
两者不同在于,sync 命令仅反对全量复制过程,psync 反对全量和局部复制。
介绍同步之前,先介绍几个概念:
runId:每个 redis 节点启动都会生成惟一的 uuid,每次 redis 重启后,runId 都会发生变化。
offset:主节点和从节点都各自保护本人的主从复制偏移量 offset,当主节点有写入命令时,offset=offset+ 命令的字节长度。从节点在收到主节点发送的命令后,也会减少本人的 offset,并把本人的 offset 发送给主节点。这样,主节点同时保留本人的 offset 和从节点的 offset,通过比照 offset 来判断主从节点数据是否统一。
repl_backlog_size:保留在主节点上的一个固定长度的先进先出队列,默认大小是 1MB。
主节点发送数据给从节点过程中,主节点还会进行一些写操作,这时候的数据存储在复制缓冲区中。从节点同步主节点数据实现后,主节点将缓冲区的数据持续发送给从节点,用于局部复制。
主节点响应写命令时,岂但会把命名发送给从节点,还会写入复制积压缓冲区,用于复制命令失落的数据补救。
下面是 psync 的执行流程:
从节点发送 psyncrunId 命令,主节点有三种响应:
FULLRESYNC:第一次连贯,进行全量复制
CONTINUE:进行局部复制
ERR:不反对 psync 命令,进行全量复制
全量复制和局部复制的过程
下面是全量复制的流程。次要有以下几步:
从节点发送 psync ? - 1 命令(因为第一次发送,不晓得主节点的 runId,所以为?,因为是第一次复制,所以 offset=-1)。
主节点发现从节点是第一次复制,返回 FULLRESYNC {runId} {offset},runId 是主节点的 runId,offset 是主节点目前的 offset。
从节点接管主节点信息后,保留到 info 中。
主节点在发送 FULLRESYNC 后,启动 bgsave 命令,生成 RDB 文件(数据长久化)。
主节点发送 RDB 文件给从节点。到从节点加载数据实现这段期间主节点的写命令放入缓冲区。
从节点清理本人的数据库数据。
从节点加载 RDB 文件,将数据保留到本人的数据库中。
- 如果从节点开启了 AOF,从节点会异步重写 AOF 文件。
对于局部复制有以下几点阐明:
1、局部复制次要是 Redis 针对全量复制的过高开销做出的一种优化措施,应用 psyncrunId 命令实现。当从节点正在复制主节点时,如果呈现网络闪断或者命令失落等异常情况时,从节点会向主节点要求补发失落的命令数据,主节点的复制积压缓冲区将这部分数据间接发送给从节点,这样就能够放弃主从节点复制的一致性。补发的这部分数据个别远远小于全量数据。
2、主从连贯中断期间主节点仍然响应命令,但因复制连贯中断命令无奈发送给从节点,不过主节点内的复制积压缓冲区仍然能够保留最近一段时间的写命令数据。
3、当主从连贯复原后,因为从节点之前保留了本身已复制的偏移量和主节点的运行 ID。因而会把它们当做 psync 参数发送给主节点,要求进行局部复制。
4、主节点接管到 psync 命令后首先核查参数 runId 是否与本身统一,如果统一,阐明之前复制的是以后主节点;之后依据参数 offset 在复制积压缓冲区中查找,如果 offset 之后的数据存在,则对从节点发送 +COUTINUE 命令,示意能够进行局部复制。因为缓冲区大小固定,若产生缓冲溢出,则进行全量复制。
5、主节点依据偏移量把复制积压缓冲区里的数据发送给从节点,保障主从复制进入失常状态。
Redis 主从复制会存在以下问题:
- 一旦主节点宕机,从节点降职为主节点,同时须要批改利用方的主节点地址,还须要命令所有从节点去复制新的主节点,整个过程须要人工干预。
- 主节点的写能力受到单机的限度。
- 主节点的存储能力受到单机的限度。
- 原生复制的弊病在晚期的版本中也会比较突出,比方:redis 复制中断后,从节点会发动 psync。此时如果同步不胜利,则会进行全量同步,主库执行全量备份的同时,可能会造成毫秒或秒级的卡顿。
所以用哨兵解决以上问题。
哨兵的性能
Redis Sentinel(哨兵)次要性能包含主节点存活检测、主从运行状况检测、主动故障转移、主从切换。Redis Sentinel 最小配置是一主一从。
Redis 的 Sentinel 零碎能够用来治理多个 Redis 服务器,该零碎能够执行以下四个工作:
- 监控:一直查看主服务器和从服务器是否失常运行。
- 告诉:当被监控的某个 redis 服务器呈现问题,Sentinel 通过 API 脚本向管理员或者其余应用程序发出通知。
- 主动故障转移:当主节点不能失常工作时,Sentinel 会开始一次主动的故障转移操作,它会将与生效主节点是主从关系的其中一个从节点降级为新的主节点,并且将其余的从节点指向新的主节点,这样人工干预就能够免了。
- 配置提供者:在 Redis Sentinel 模式下,客户端利用在初始化时连贯的是 Sentinel 节点汇合,从中获取主节点的信息。
哨兵的原理
1、每个 Sentinel 节点都须要定期执行以下工作:每个 Sentinel 以每秒一次的频率,向它所知的主服务器、从服务器以及其余的 Sentinel 实例发送一个 PING 命令。(如上图)
2、如果一个实例间隔最初一次无效回复 PING 命令的工夫超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel 标记为主观下线。(如上图)
3、如果一个主服务器被标记为主观下线,那么正在监督这个服务器的所有 Sentinel 节点,要以每秒一次的频率确认主服务器确实进入了主观下线状态。
4、如果一个主服务器被标记为主观下线,并且有足够数量的 Sentinel(至多要达到配置文件指定的数量)在指定的工夫范畴内批准这一判断,那么这个主服务器被标记为主观下线。
5、个别状况下,每个 Sentinel 会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令,当一个主服务器被标记为主观下线时,Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率,会从 10 秒一次改为每秒一次。
6、Sentinel 和其余 Sentinel 协商主观下线的主节点的状态,如果处于 SDOWN 状态,则投票主动选出新的主节点,将残余从节点指向新的主节点进行数据复制。
7、当没有足够数量的 Sentinel 批准主服务器下线时,主服务器的主观下线状态就会被移除。当主服务器从新向 Sentinel 的 PING 命令返回无效回复时,主服务器的主观下线状态就会被移除。
点击关注,第一工夫理解华为云陈腐技术~