Redis 多机方案

Redis主从复制

Redis服务器角色可以分为主服务器和从服务器, 从服务器复制主服务。通过在指定服务器上执行SLAVEOF可以将服务器设置为目标服务器的从服务器, 目标服务器成为主服务器。

SLAVEOF 127.0.0.1 6379

同步实现

同步包括SLAVEOF触发的复制和建立主从关系后的命令同步。

复制流程如下:

  1. 从服务器向主服务器发送SYNC命令
  2. 主服务器接收到SYNC命令后,执行BGSAVE命令, 在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
  3. 当主服务器的BGSAVE命令执行完毕后, 主服务器将生成的RDB文件发送给从服务器,从服务器接收RDB文件后,加载数据。
  4. 主服务器将记录在缓冲区中的所有写入命令发送给从服务器, 从服务器执行同步主服务的状态。

命令传播:每当主服务器收到写入命令,数据发生变化,都将命令传播到从服务器执行。

增量复制

PSYNC 是在SYNC命令的基础上提供了全量同步和增量同步(部分重同步)的模式,用于处理从服务器断线重连主服务器的数据同步场景。

  1. 全量同步: 同SYNC的复制流程一致
  2. 增量同步: 当从服务器断线重连主服务器后, 主服务器只将从服务器断线期间的命令同步至从服务器,避免全量同步带来的性能问题。

增量同步的实现通过复制缓冲区+复制偏移量来实现:

主从服务器都维护自己同步的复制偏移量,服务器同步命令将将写入复制缓冲区, 当从服务器同主服务器建立连接进行数据同步时,检查偏移量,如果偏移量不一致,并且从服务器的偏移量还存在复制缓存区,则主服务器将从服务器偏移量之后的数据同步到从服务器即可,如果已经被清理出复制缓冲区,进行完全同步。

命令同步

主节点执行完一条写命令,立即返回客户端,异步发送写命令同步给从节点

心跳检测

       从服务器默认每秒一次的频率向主服务器发送命令。

Redis 针对主从复制的配置:

       Min-salves-to-write : 接收写命令时最少网络连接正常的从服务器数量。如不满足条件,拒绝写命令。

Min-salves-max-lag: 接收写命令时,从服务器的延迟最大值。如超过,拒绝。

Redis Setinel

Sentinel集群是Redis高可用性的解决方案: 由一个或多个Sentinel实例组成的Sentinel系统监控任意多个主服务器以及这些主服务器下属的所有从服务器, 当某个主服务器进入下线状态时,自动从该主服务器的从服务器中选择一个从服务器升级为主服务器继续处理命令。当原先下线的主服务器重新上线后将成为新主服务器的从服务器。

Sentinel通过INFO命令获取主服务器信息及其从服务器地址。建立同主服务器和从服务器的连接。

Sentinel将Sentinel信息通过发布订阅的形式推送给监控的主从节点,Sentinel之间则通过服务器状态获取其他存在的Sentinel节点信息,建立相关之间的连接。

Sentinel将同其他Sentinel示例,监控的主服务器、主服务器的从服务器都建立连接,后续通过PING命令检查响应节点的存活性。

主服务器的下线状态

主观下线状态: 当Sentinel在特定时间内无法获取监控主服务器的PING命令有效响应,则将该主服务器设置为主观下线状态。

客观下线状态:当Sentinel判断某个主服务器为主观下线状态,则向监控该主服务器的其它Sentinel进行确认,如果得到确认下线响应的Sentinel数量达到配置的quorum,则判定该主服务器客观下线。

Sentinel leader选举

当一个主服务器被判断为客观下线时, 监视该主服务器的Sentinel节点实例通过选举算法选择Sentinel的Leader 负责对主服务器进行故障转移。

选举流程如下:

  1. 每一轮选举都通过一个轮次标识来确定。
  2. 在某次配置轮次中, 当某个Sentinel确认主服务器达到客观下线状态后,将自己设置为该轮次的Leader,并向其它Sentinel进行确认。
  3. Sentinel的Leader按先到先的的规则, 当某个Sentinel在没有设置Leader节点时收到其他Sentinel的选举请求,将该选举请求中指定的Leader设置为本节点,本轮次的leader,并返回回复确认。
  4. 如果某个轮次中,一个Sentinel节点得到超过半数Sentinel节点的确认,将成为Leader。
  5. 如果在特定时间内没有选举成功Sentinel leader,则生轮次,重新选举。
  6. 不管选举是否成功,一次选举后轮次都将自增一次。

故障转移

过程包括:

  1. 从所有从服务器节点中选择主服务器:按优先级+复制偏移量进行选择。 发送SLAVEOF no one命令将该从服务器设置为主服务器。
  2. 将其他从服务器改为复制新的主服务器
  3. 将重新上线的原主服务器节点改为复制新

Redis 集群

Redis集群是Redis提供的分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故障转移功能。

组成集群

通过CLUSTER MEET IP PORT将自身同目标节点纳入同一个集群中。

CLUSTER MEET 127.0.0.1 7001

可以通过CLUSTER NODES 查看集群中所有节点。其他如CLUSTER INFO查看集群信息

槽指派(分片)

集群整个数据库被划分为16384个槽位,通过指派将槽位分配到不同的集群节点负责。

CLUSTER ADDSLOTS 0 1 2 3 4 … 5000

每个集群节点的槽位分配信息将传播到其他集群节点。

集群命令执行流程

集群命令执行流程如下:

  1. 客户端向节点发送数据库键指令。
  2. 节点计算键属于哪个槽位。
  3. 检查当前节点是否负责处理该槽位, 如负责则执行命令, 否则节点向客户端返回一个MOVED错误。
  4. 客户端根据MOVED错误提供目标地址将命令重新发送到负责节点执行。

槽位确认算法: CRC16(KEY) & 16383

重新分片

Redis集群的重新分片(重新进行槽位分配)由集群管理软件redis-trib负责。

相关的质量包括:

  1. 往目标节点发送CLUSTER SETSLOT  <SLOT> IMPORTING <SOURCE_ID>: 通知目标节点准备好从源节点导入SLOT相关的键
  2. 往源节点发送CLUSTER GETKEYSINSLOT <SLOT> <COUNT>获取源节点指定SLOT,指定数量的建。
  3. 将获取到的key通过命令MIGRATE <TARGET_IP> <TARGET_PORT> <KEY_NAME> 0 <TIME_OUT>通知源节点将被选中的键迁移到目标节点,持续进行该命令。直到完成SLOT的迁移
  4. 最后向任意一个节点发送 CLUSTER SETSLOT <SLOT> NODE <TARGET_ID>通知槽指配信息的迁移,该信息会广播到集群所有节点。
迁移过程中的命令处理

       迁移过程中,按照原槽位指派信息,原节点收到键命令,如果键还没有迁移到目标节点,则原节点处理并返回。如果已经迁移走,则原节点返回一个ASK命令指示客户端跳转到目标节点进行处理。

       ASK和MOVED命令都指示客户端切换节点目标,MOVED命令是依据槽位归属的产生的跳转, ASK只用于在进行重新分片过程中产生的临时跳转。

复制和故障转移

集群中节点也按照主从概念划分为主节点和从节点, 主节点用于处理槽中键的命令, 从节点用于复制主节点,并在主节点下线后代替下线主节点继续处理命令。

CLUSTER REPLICATE <NODE_ID>将节点设置为NODE_ID的从节点。

故障检测

集群中的每一个节点会定期向集群中的其它节点发送PING消息检测目标节点的在线情况, 如果在规定时间内没有接收到PING消息的正常响应,节点会将目标节点设置为疑似下线状态。

集群中节点相互通过消息交换自身维护的集群节点状态,如果集群中超过半数的主节点都将某个主节点报告为疑似下线, 则设置为下线状态。并在集群中进行广播该主节点的下线状态。

故障转移

当从节点收到主节点下线的消息, 将触发主节点的选举。选举过程同Sentinel对主节点的选举过程类似, 只是负责选举的绝点变成集群中的所有主节点,当超过半数的主节点选举出新的从节点,当选为新主节点的从节点将负责进行故障转移:

  1. 执行SLAVEOF NO ONE 成为新的主节点
  2. 撤销原先主节点的槽位指派,并重新指派到自己身上。
  3. 广播PONG消息,通知自身成为新的主节点,其他的从节点将修改为新主节点的从节点。
  4. 后续有新的主节点负责处理槽位相关的键命令。
11-09 08:43