(三)Redis主从复制介绍

1.什么是主从复制

1.1 简介

在分布式环境中,数据副本 (Replica) 和复制 (Replication) 作为提升系统可用性和读写性能的有效手段被大量应用系统设计中,Redis 也不例外。Redis 作为单机数据库使用时,适用常见有限且存在单点宕机问题,无法维持高可用。因此 Redis 允许通过 SLAVEOF 命令或者 slaveof 配置项来让一个 Redis server 复制另一个 Redis server 的数据集和状态,我们称之为主从复制,主服务器下文称 master,从服务器下文称 slave,Redis 采用异步的复制机制。

复制机制的运行依靠三个特性:

  1. 当一个 master 和一个 slave 连接正常时,master 会发送一连串的命令流来保持对 slave 的更新,以便于将自身数据集的变更复制给 slave :包括客户端的写入、key 的过期或被逐出等

  2. masterslave 之间的连接断开后(断开的原因可能是网络问题或者连接超时) slave 重连上 master 并尝试进行部分重同步,这意味着它只会尝试获取在断开连接期间内丢失的命令流

  3. 当无法进行部分重同步时, slave 会请求进行全量重同步。这会涉及到一个更复杂的过程,例如 master 需要创建所有数据的快照,将之发送给 slave ,之后在数据集更改时持续发送命令流到 slave

1.2 主从复制的优点

  • master 可以关闭持久化机制,减少不必要的 IO 操作且降低延迟,对于以性能著称的组件来说极为重要

  • slave 虽然不能处理写请求,但是可以处理读请求,从而增加读取操作的吞吐量。但由于复制机制的原因,主从数据存在不一致的时间窗口

  • 使得 Redis 可以告别单机版本的单点风险,采用副本形式提高可用性,在 master 宕机时可以将 slave 提升为 master 继续向外提供服务,也为 Redis 集群模式的诞生奠定了技术基础

这里需要注意的是 Redis 2.8 版本之前与之后采用的复制方式不尽相同,主要区别在将成本极高的 sync 替换为 psync,增加了断线重连情况下根据主从保存的 offset 即复制偏移量进行增量同步的功能。

1.3 主从复制的缺点

a)主从复制,若主节点出现问题,则不能提供服务,需要人工修改配置将从变主
b)主从复制主节点的写能力单机,能力有限
c)单机节点的存储能力也有限

1.4 主从复制和集群

有时我们会混淆这两个概念,主从复制也是采用了多个 Redis 节点,和 Redis 集群表面上看很接近,那二者究竟有什么区别呢?

Replication

复制机制中包含了一个 master 和若干个 slave,其中写请求只能 master 来处理,数据的变更转化为数据流异步发送给 slaves 进行更新;读请求则可以根据使用场景来规定是否由 slave 处理从而增加系统的读吞吐量。一旦 master 发生故障,slave 可以被提升为 master 从而继续提供服务。因此总结起来,slave 在复制机制的场景下,可以提供故障恢复、分担读流量和数据备份的功能。

Cluster

集群机制的使用意味着你的数据量较大,数据会根据 Key 计算出的 slot 值自动在多个分片上进行分区(Partitioning),客户端对某个 Key 的请求会被转发到持有那个 Key 的分片上。分片由一个 master 和若干个 slave 组成,二者间通过复制机制同步数据。因此总结来看,集群模式更像分区和复制机制的组合。

2. 主从复制机制的演变

从 Redis 2.6 到 4.0 开发人员对复制流程进行逐步的优化,以下是演进过程:

  • 2.8 版本之前 Redis 复制采用 sync 命令,无论是第一次主从复制还是断线重连后再进行复制都采用全量同步,成本高

  • 2.8 ~ 4.0 之间复制采用 psync 命令,这一特性主要添加了 Redis 在断线重连时候可通过 offset 信息使用部分同步

  • 4.0 版本之后也采用 psync,相比于 2.8 版本的 psync 优化了增量复制,这里我们称为 psync2,2.8 版本的 psync 可以称为 psync1

3. 主从复制的原理

主从复制过程可分为三个阶段:复制初始化、数据同步和命令传播。

复制初始化阶段

当执行完 slaveof 命令后,slave 根据指明的 master 地址向 master 发起 socket 连接,master 收到 socket 连接之后将连接信息保存,此时连接建立完成;当 socket 连接建立完成以后,slavemaster 发送 PING 命令,以确认 master 是否存活,此时的结果返回如果是 PONG 则代表 master 可用,否则可能出现超时或者 master 此时在处理其他任务阻塞了,那么此时 slave 将断开 socket 连接,然后进行重试;

如果 master 连接设置了密码,则 slave 需要设置 masterauth 参数,此时 slave 会发送 auth 命令,命令格式为 auth + 密码 进行密码验证,其中密码为 masterauth 参数配置的密码,需要注意的是如果 master 设置了密码验证,从库未配置 masterauth 参数则会报错,socket 连接断开。当身份验证完成以后,slave 发送自己的监听端口,master 保存其端口信息,此时进入下一个阶段:数据同步阶段。

数据同步阶段

masterslave 都确认对方信息以后,便可开始数据同步,此时 slave 向主库发送 psync 命令(需要注意的是 redis 4.0 对 2.8 版本的 psync 做了优化),主库收到该命令后判断是进行增量同步还是全量同步,然后根据策略进行数据的同步,当 master 有新的写操作时候,此时进入复制第三阶段:命令传播阶段。

命令传播阶段

当数据同步完成以后,在此后的时间里 master-slave 之间维护着心跳检查来确认对方是否在线,每隔一段时间(默认10秒,通过 repl-ping-slave-period 参数指定)masterslave 发送 PING 命令判断 slave 是否在线,而 slave 每秒一次向 master 发送 REPLCONF ACK 命令命令格式为:REPLCONF ACK {offset} ,其中 offsetslave 保存的复制偏移量,作用有:

  • 汇报自己复制偏移量,master 会对比复制偏移量向 slave 发送未同步的命令

  • 判断 master 是否在线

slave 接送命令并执行,最终实现与主库数据相同

4.主从故障如何故障转移

a)主节点(master)故障,从节点slave-1端执行 slaveof no one后变成新主节点;
b)其它的节点成为新主节点的从节点,并从新节点复制数据;
c)需要人工干预,无法实现高可用。

5.Redis哨兵机制

1. 为什么要有哨兵机制?

       哨兵机制的出现是为了解决主从复制的缺点的。

2. 哨兵机制(sentinel)的高可用

  原理:当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。

其实整个过程只需要一个哨兵节点来完成,首先使用Raft算法(选举算法)实现选举机制,选出一个哨兵节点来完成转移和通知。

3. 哨兵的定时监控任务

任务1:每个哨兵节点每10秒会向主节点和从节点发送info命令获取最拓扑结构图,哨兵配置时只要配置对主节点的监控即可,通过向主节点发送info,获取从节点的信息,并当有新的从节点加入时可以马上感知到

任务2:每个哨兵节点每隔2秒会向redis数据节点的指定频道上发送该哨兵节点对于主节点的判断以及当前哨兵节点的信息,同时每个哨兵节点也会订阅该频道,来了解其它哨兵节点的信息及对主节点的判断,其实就是通过消息publish和subscribe来完成的

 任务3:每隔1秒每个哨兵会向主节点、从节点及其余哨兵节点发送一次ping命令做一次心跳检测,这个也是哨兵用来判断节点是否正常的重要依据

客观下线:当主观下线的节点是主节点时,此时该哨兵3节点会通过指令sentinel is-masterdown-by-addr寻求其它哨兵节点对主节点的判断,当超过quorum(选举)个数,此时哨兵节点则认为该主节点确实有问题,这样就客观下线了,大部分哨兵节点都同意下线操作,也就说是客观下线

 

4. 领导者哨兵选举流程

a)每个在线的哨兵节点都可以成为领导者,当它确认(比如哨兵3)主节点下线时,会向其它哨兵发is-master-down-by-addr命令,征求判断并要求将自己设置为领导者,由领导者处理故障转移;
b)当其它哨兵收到此命令时,可以同意或者拒绝它成为领导者;
c)如果哨兵3发现自己在选举的票数大于等于num(sentinels)/2+1时,将成为领导者,如果没有超过,继续选举…………

 

5. 故障转移机制

a)由Sentinel节点定期监控发现主节点是否出现了故障

sentinel会向master发送心跳PING来确认master是否存活,如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了

 

 

 b) 当主节点出现故障,此时3个Sentinel节点共同选举了Sentinel3节点为领导,负载处理主节点的故障转移

 

 c) 由Sentinel3领导者节点执行故障转移,过程和主从复制一样,但是自动执行

 

 流程:

    1. 将slave-1脱离原从节点,升级主节点,

         2. 将从节点slave-2指向新的主节点

         3. 通知客户端主节点已更换

         4. 将原主节点(oldMaster)变成从节点,指向新的主节点

 d) 故障转移后的redis sentinel的拓扑结构图

你可能感兴趣的:(Redis,Redis)