Failover

当源 Redis 实例发生故障时,需要先对灾备集群进行容灾故障切换,然后将客户端的访问地址切换到新的灾备实例。

目录

灾备集群切换

在灾备集群中,当源发生故障时,需要中断与故障源的同步链路,将目标端提升为源;以确保客户端可以写入数据,且故障源的脏数据不会污染目标实例。

故障切换时机说明

当灾备集群的源发生故障时,目标端的 Alauda Cache Service for Redis OSS 会检测到与源的灾备链路中断,此时 ActiveRedisConnection 资源状态异常,目标实例的 Web 控制台会提示可以进行灾备切换。

灾备切换风险说明
需要注意的是,该异常提示仅为交互式告警提示,不应作为客户端可以执行灾备切换的唯一判断依据。

灾备切换

CLI
Web Console

查看连接状态

# 查看正常状态
$ kubectl -n default get activeredisconnections
NAME           INSTANCE   STATUS    MESSAGE   AGE
c6-dest-conn   c6-dest    Healthy             35s

# 查看异常状态
$ kubectl -n default get activeredisconnections
NAME           INSTANCE   STATUS   MESSAGE                                                                                          AGE
c6-dest-conn   c6-dest    Failed   shard 0 status is Disconnected; shard 1 status is Disconnected; shard 2 status is Disconnected   86s

STATUSFailed 时,表示实例 c6-dest 与上游的连接异常。可以查看 yaml 详情了解具体情况:

$ kubectl -n default get activeredisconnections c6-dest-conn -o yaml
apiVersion: redis.middleware.alauda.io/v1alpha1
kind: ActiveRedisConnection
metadata:
  annotations:
    cpaas.io/creator: admin
    cpaas.io/updated-at: "2025-08-27T08:42:16Z"
  creationTimestamp: "2025-08-27T08:42:16Z"
  generation: 1
  labels:
    cpaas.io/activeredis: c6-dest-activeredis
    cpaas.io/activeredis-instance: c6-dest
  name: c6-dest-conn
  namespace: default
  ownerReferences:
  - apiVersion: redis.middleware.alauda.io/v1alpha1
    blockOwnerDeletion: true
    controller: true
    kind: ActiveRedis
    name: c6-dest-activeredis
    uid: ed1010f8-a70d-42ef-be19-0450478df137
  resourceVersion: "19592690"
  uid: 301f77be-ff52-4e50-98d0-d85a38e2415a
spec:
  addresses:
  - 192.168.1.11:30011
  instance: c6-dest
  pause: true
  secretName: c6-dest-conn-password
status:
  instance: c6-dest
  message: shard 0 status is Disconnected; shard 1 status is Disconnected; shard 2
    status is Disconnected
  shards:
  - index: 0
    offset: "0"
    opId: "0"
    status: Disconnected
    syncStatus: PartialSync
  - index: 1
    offset: "0"
    opId: "0"
    status: Disconnected
    syncStatus: PartialSync
  - index: 2
    offset: "0"
    opId: "0"
    status: Disconnected
    syncStatus: PartialSync
  status: Failed
  upstreamPeer:
    service_id: 0
    service_metadata:
      instance: default/c6

与源断开连接

在人工确认源确实异常后,需要断开目标实例与源的灾备链路,防止脏数据引入。

$ kubectl -n default delete activeredisconnections c6-dest-conn

删除对应的 ActiveRedisConnection 资源后,Redis 实例已成为独立的源实例,客户端访问地址即可安全切换至该实例进行读写。

将故障源作为新源的目标实例

故障源恢复正常后,可以重新加入灾备集群,作为新源的目标实例。具体操作方法请参考 Setup Disaster Recovery

客户端侧灾备切换

客户端在连接灾备集群前,应支持在检测到源故障后,将 Redis 访问地址切换到新源实例(被提升的目标)。通常有以下切换方式:

架构机制优点缺点对 RTO/RPO 的影响实现难度理想使用场景
DNS 切换更新 DNS 记录指向新的 IP概念简单,平台无关。RTO 长且不可控(依赖 TTL),对 K8s 内部流量无效。RTO:分钟级
RPO:可能较高。
对 RTO 要求低的应用,或作为人工回退方案。
代理客户端连接代理,代理通过健康检查路由到主节点。切换快速(秒级 RTO),对客户端透明,故障恢复简单。增加网络跳数和运维负担,代理本身需高可用。RTO:秒级
RPO:低。
推荐方案:需要快速透明切换,且具备运维高可用代理集群能力。
Service Mesh (Istio)Sidecar 代理拦截流量,基于策略进行本地优先级和跨集群切换。功能强大,应用透明,故障恢复简单。运维复杂度极高,技术栈重。RTO:秒级
RPO:低。
已全面采用 Service Mesh 管理微服务的大型复杂系统。
客户端库库内置逻辑,自行决定切换到目标集群。无中间层,延迟可能更低。风险极高:切换决策不可靠,故障恢复复杂(通常需重启业务),生态支持不一致。RTO:不可预测
RPO:高风险。
不推荐用于生产级自动灾备。

客户端是否触发灾备故障切换,不能仅凭二元判断,故障切换是一个多维度、高置信度的决策过程。需要结合多维度的故障检测,包括但不限于:实例可用状态实例是否仍具备高可用k8s 集群是否可能继续提供服务数据中心可用性检测

通常,客户端安全执行灾备切换前需满足如下表达式:

(手动触发切换)
OR
(
  (源实例状态检测失败,且连续失败 N 次)
  AND
  (
    (实例不再具备高可用)
    OR
    (数据中心可用性检测失败,且连续失败 N 次)
  )
  AND
  (目标实例可用状态检测通过)
)
支持说明

Alauda Cache Service for Redis OSS 目前不提供客户端侧灾备切换支持,客户需根据自身基础设施实现合适的客户端切换方案。