1. 概述

在本教程中,我们将学习如何使用 Helm Chart 在 Kubernetes 集群上部署高可用的 Redis 集群。此外,我们还将通过一个演示来观察故障转移机制是如何工作的。

2. Redis 主从复制与 Sentinel

高可用性(High Availability,HA)是指系统在大部分时间内保持运行和可访问的能力。通常,一个 HA 系统包含多个备用实例,称为副本(replica)。这些副本从主节点(primary)接收更新,以保持其状态与主节点接近。当主节点失效时,其中一个副本可以接管主节点角色,从而最小化数据丢失。许多系统如 PostgreSQL、Redis 和 Elasticsearch 都支持这种 HA 部署。

2.1. Redis 中的高可用性

在 Redis 的上下文中,部署 HA Redis 服务意味着除了主节点外,还要运行多个副本节点。副本节点连接到主节点以接收写操作变更。主节点与多个副本节点一起构成一个 HA Redis 集群。在本文中,我们使用小写的 “cluster” 来指代由多个副本组成的实际 Redis 集群,而不是 Redis Cluster 软件。

2.2. Redis Sentinel

Redis Sentinel(简称 Sentinels)是一个与 Redis 实例并行运行的独立进程。在 Kubernetes 部署中,Sentinel 通常作为与 Redis 容器位于同一 Pod 中的另一个容器运行。

当主节点失效时,每个 Redis 实例上的 Sentinel 会触发故障转移。它通过持续监控集群中各节点的健康状态来实现。当发生故障时,集群中剩余的 Sentinel 会达成共识,并将一个副本节点提升为新的主节点。

3. 部署高可用 Redis

使用 Redis Helm Chart 是部署 HA Redis 的最便捷方式。相比分别部署各个组件,Helm Chart 会将所有必要组件作为一个整体进行部署。此外,Redis Helm Chart 还提供了多种可配置参数。

3.1. 获取 Redis Helm Chart

要安装 Redis Helm Chart,首先需要通过 apt-get 安装 helm 工具:

$ sudo apt-get install -y helm

然后添加 Bitnami 的 Helm Chart 仓库:

$ helm repo add bitnami https://charts.bitnami.com/bitnami

添加完成后,我们就可以访问 Bitnami 提供的 Redis Helm Chart。

3.2. 配置 Redis Helm Chart 安装参数

Bitnami Redis Helm Chart 的默认配置仅部署了一个不带 Sentinel 的 Redis StatefulSet。我们可以通过 values.yaml 文件来启用 Sentinel:

$ cat > values.yaml <<EOF
global:
  redis:
    password: password
replica:
  replicaCount: 2
sentinel:
  enabled: true
EOF

上述命令将配置写入 values.yaml 文件。其中:

  • 设置密码为 password
  • 副本数量设为 2,即部署两个副本
  • 启用 Sentinel(sentinel.enabled: true

3.3. 安装 Redis Helm Chart

使用以下命令安装 Redis Helm Chart:

$ helm install redis-sentinel bitnami/redis --values values.yaml

该命令将 bitnami/redis Chart 安装为名为 redis-sentinel 的 release,并使用 values.yaml 文件进行自定义配置。

3.4. 检查部署状态

我们可以通过以下命令查看 StatefulSet 是否部署成功:

$ kubectl get statefulset
NAME                  READY   AGE
redis-sentinel-node   3/3     9m36s

StatefulSet 会创建 3 个 Pod,其中一个是主节点,另外两个是副本节点:

$ kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
redis-sentinel-node-0   2/2     Running   0          10m
redis-sentinel-node-1   2/2     Running   0          8m59s
redis-sentinel-node-2   2/2     Running   0          8m33s

每个 Pod 中都包含两个容器:redis 和 sentinel。可以通过以下命令确认:

$ kubectl top pod --containers
POD                     NAME       CPU(cores)   MEMORY(bytes)
redis-sentinel-node-0   redis      14m          8Mi
redis-sentinel-node-0   sentinel   13m          7Mi
...

4. 实战:高可用 Redis 集群测试

我们来测试 HA Redis 集群的故障转移能力。我们将运行一个持续递增计数器的客户端脚本,然后模拟主节点故障,观察客户端是否能自动切换到新的主节点。

4.1. Redis 客户端脚本

首先,我们创建一个运行 Redis 客户端的 Pod:

$ kubectl run redis-client --restart='Never' --image redis --command -- sleep infinity

然后进入该 Pod 并创建一个脚本:

$ kubectl exec --tty -i redis-client -- bash

创建 client-increment.sh 脚本如下:

$ cat client-increment.sh
#!/bin/bash
export REDISCLI_AUTH=password
while true
do
    CURRENT_PRIMARY=$(redis-cli -h redis-sentinel -p 26379 SENTINEL get-master-addr-by-name mymaster)
    CURRENT_PRIMARY_HOST=$(echo $CURRENT_PRIMARY | cut -d' ' -f1 | head -n 1)
    echo "Current master's host: $CURRENT_PRIMARY_HOST"
    redis-cli -h ${CURRENT_PRIMARY_HOST} -p 6379 INCR mycounter
    sleep 1
done

脚本说明:

  • 设置 Redis 认证密码
  • 使用 SENTINEL get-master-addr-by-name 获取当前主节点地址(注意使用 Sentinel 端口 26379)
  • 使用 cuthead 提取主节点 Hostname
  • 每秒对 mycounter 进行一次自增操作

运行脚本后输出如下:

Current master's host: redis-sentinel-node-0.redis-sentinel-headless.default.svc.cluster.local
(integer) 1
Current master's host: redis-sentinel-node-0.redis-sentinel-headless.default.svc.cluster.local
(integer) 2
...

4.2. 模拟主节点故障并观察故障转移

打开一个新终端,删除主节点 Pod:

$ kubectl delete pods redis-sentinel-node-0
pod "redis-sentinel-node-0" deleted

观察客户端输出变化:

...
Current master's host: redis-sentinel-node-0.redis-sentinel-headless.default.svc.cluster.local
(integer) 18
Current master's host: redis-sentinel-node-0.redis-sentinel-headless.default.svc.cluster.local
(integer) 19
Current master's host: redis-sentinel-node-0.redis-sentinel-headless.default.svc.cluster.local
Error: Server closed the connection
Current master's host: redis-sentinel-node-2.redis-sentinel-headless.default.svc.cluster.local
(integer) 20
Current master's host: redis-sentinel-node-2.redis-sentinel-headless.default.svc.cluster.local
(integer) 21
...

✅ 可以看到:

  • 主节点宕机后,客户端短暂报错
  • 随后自动切换到新的主节点 redis-sentinel-node-2
  • 计数器继续递增,未丢失数据

5. 总结

在本教程中,我们了解了高可用性的基本概念,以及 Redis 如何通过副本实现高可用。Redis Sentinel 机制可以监控主节点状态并在其失效时触发故障转移。

我们还学习了如何使用 Bitnami 提供的 Redis Helm Chart 快速部署 HA Redis 集群,并通过一个客户端脚本验证了故障转移机制的有效性。

📌 踩坑提醒

  • ✅ Sentinel 端口是 26379,不是 6379
  • ❌ 不要使用单副本部署,否则无法实现 HA
  • ⚠️ 故障转移过程中客户端会短暂断开连接,需做好重试机制


原始标题:Redis Sentinel High Availability on Kubernetes