Redis 集群主要特性&原理复习

相关问题

1. 集群架构
2. 扩容过程
3. 扩容过程中定位元素的过程
4. 重定向 ASK & MOVED
5. 客户端更新slot和节点的映射关系
4. 集群容错
5. 故障检测
6. 选主&晋升
7. 副本迁移算法

集群扩容 & 新增节点

扩容对应着集群新增节点,步骤如下:

  1. 启动redis节点 加入集群设置为Master节点
  2. 为当前增加的master节点增加slave节点[master节点没分配slot前不会实际进行工作]
  3. 准备slot的数据迁移。可以选择 all所有数据源 nodeId指定数据源。也就是reShared操作。
  4. 迁入数据slot状态设置为: IMPROTING
  5. 迁出数据slot状态设置为:MIGRATING
  6. 数据迁移完成,广播更新slot和nodeId的映射信息,扩容完成。

以上4&5顺序不能乱。
假设我们有两个 Redis 主节点,分别称为 A 和 B。我们想将哈希槽 8 从 A 移动到 B,因此我们发出如下命令:

  • 迁入节点B: CLUSTER SETSLOT 8 IMPORTING[from] A 在目标节点设置 迁入slot 从源节点。
  • 迁出节点A:CLUSTER SETSLOT 8 MIGRATING [to] B 在迁出的节点设置 移动slot到目标。

若顺序乱且迁出设置迁入还未设置: 客户端访问A对应slot 重定向到B B对应slot找不到数据,且未设置 IMPORTING。会返回moved A & slot.形成死。

正在扩容的节点如何提供数据访问

迁出的节点

  1. 迁出的slot状态为:MIGRATING
    若待查询数据存在,正常返回,若查询数据正在migrate状态当中,会阻塞等命令结束继续处理客户端请求,若待查询数据不存在,返回ASK以及目标节点的信息。此时客户端会带上ASKING信息去查询目标节点。所有不存在的查询都会重定向到MIGRATING的slot上。

  2. 目标slot状态为:IMPORTING
    节点会接受当前slot所有携带ASKING的查询。若查询是客户端发起,正常返回,若查询非客户端发起,则会返回MOVED&对该次查询绑定真实slot的目标节点。

MOVED & ASK 差异

  1. 如果收到 ASK 重定向,则只发送被重定向到指定节点的查询,但继续向旧节点发送后续查询。
  2. 使用 ASKING 命令启动重定向查询。ASKING 命令在客户端上设置一个一次性标志,强制节点为有关 IMPORTING 插槽的查询提供服务。
  3. 不要更新本地客户端表以将 slot 映射到新的节点上。
       
    从A->B 迁移到B
    一旦哈希槽 8 迁移完成,A 将发送一条 MOVED 消息,客户端可以将哈希槽 8 永久映射到新的 IP 和端口对。请注意,如果有问题的客户端更早地执行映射,这不是问题,因为它不会在发出查询之前发送 ASKING 命令,因此 B 将使用 MOVED 重定向错误将客户端重定向到 A。

客户端更新slot和节点的映射关系

两种情况下,客户端通常需要获取完整的插槽列表和映射的节点地址:

  1. 在启动时填充初始插槽配置。
  2. 当MOVED收到重定向时。

客户端可以通过MOVED仅更新当前slot来处理重定向,但这通常效率不高,因为通常会同时修改多个slot映射.

集群容错 心跳和gossip消息

心跳机制是指redis cluster节点之间不停的交换ping pong信息,节点发送 ping 数据包,这将触发接收者回复 pong 数据包,节点也可以只发送pong不触发回复,ping 和 pong 数据包的总和称为心跳数据包。

故障检测

  1. 前提
    集群节点都确保不超过一半NODE_TIMEOUT时间内和其他所有节点ping/pong一次,NODE_TIMEOUT过去之前,节点还尝试重新连接与另一个节点的 TCP 链接,以确保不会因为当前 TCP 连接存在问题而认为节点不可达。
  2. PFAIL状态
    若当前节点ping某个节点在NODE_TIMEOUT时间结束都没有收到回复,则会被计为PFAILpossible fail 可能失败
  3. PFAIL升级为FAIL
    a. 某个节点,我们称之为 A,将节点 B 标记为PFAIL。
    b. 从集群中大多数主节点的角度来看,节点 A 通过gossip消息收集了有关 B 状态的信息。
    c. 大多数主人及时发出信号PFAIL或FAIL条件NODE_TIMEOUT * FAIL_REPORT_VALIDITY_MULT。(在当前实现中,有效性因子设置为 2,所以这只是两倍的NODE_TIMEOUT时间)。
    d. a/b/c满足的情况下 B被A标记为FAIL 向所有可达阶节点传递FAIL消息,且所有可达节点对B的的状态被强制标记为FAIL.

FAIL状态清除

  1. 该节点已经可达并且是一个从节点。在这种情况下,FAIL可以清除标志,因为从站没有故障转移。
  2. 该节点已经可以访问并且是一个不为任何slot提供服务的主节点。在这种情况下,FAIL可以清除标志,因为没有slot的主节点并没有真正参与集群,并且正在等待配置以加入集群。
  3. 该节点已经可以访问并且是一个主节点,但是很长一段时间(N 倍NODE_TIMEOUT)过去了,没有任何可检测的从节点提升。在这种情况下,最好重新加入集群并继续。

节点重新加入集群

  1. 当失效节点重新加入集群,且向其他节点发送心跳广播自己对slot的映射关系时,其他节点看到相同slot有当前更新的从属关系时候,UPDATE slot的新配置向 A发送消息,A更新配置。
  2. 当前master 会成为他FAIL前所管理的最后一个slot,现在对应的master节点的slave.
  3. 重新成为slave前会将映射的slot信息逐渐清空。

选举机制

选举条件:

  1. master节点处于FAIL状态。
  2. master节点对非零数量的slot提供服务。
  3. slave和master最近一次通讯时间不超过设定时间。

选举过程:

  1. 一旦 master 处于FAIL状态,slave 会在尝试被选举之前等待一小段时间,避免其他master还没收到当前master的FAIL状态而拒绝投票。
  2. slave 增加计数器currentEpoch,广播FAILOVER_AUTH_REQUEST信息,在2倍NODE_TIMEOUT等待返回。
  3. 在时间内其余master只能给同一master下的其中一个slave回复FAILOVER_AUTH_ACK。
  4. 收到FAILOVER_AUTH_ACK 超过多数的slave将成为新的master.若当前没有任何一个slave得到超过一半选票,那么尝试新的选举,且选举时间为上一次的2倍。

副本迁移算法

若某一段slot对应的master失效,slave成为新的master,且当前无新的slave. 集群将尝试从slave最多的master节点当中,将较低节点 ID 的非故障slave迁移为当前master的slave,以保证集群副本的动态平衡。

参考文档

  1. 官方文档:Redis Cluster Specification
  2. 官方文档:Redis cluster tutorial
  3. 社区沙龙:腾讯会议用户暴涨 Redis集群的无缝扩容
  4. 公司实践:前东家软测项目 Redis实践。
上一篇:mysql主从复制、读写分离


下一篇:NoSQL数据库之Redis主从同步与级联复制