it编程 > 数据库 > Redis

Redis Cluster 高可用集群部署方案详解

86人参与 • 2026-09-29 • Redis

redis cluster 高可用集群的‌标准部署方案是“3主3从”共6个节点‌,最少需要3个主节点才能形成法定多数投票机制,每个主节点至少配1个从节点用于故障自动切换,这样能容忍1个主节点及其对应从节点同时故障。‌‌

一、方案概述

1.1 目标

在已有的 k8s 高可用集群上,部署一套 redis cluster(集群模式),具备:

1.2 技术选型

组件用途
bitnami redis cluster helm chart部署 redis cluster
statefulset管理 6 个 redis pod
persistentvolumeclaim每个节点的持久化存储
redis cluster数据分片和自动故障转移

1.3 架构

应用
  ↓
service: production-redis-redis-cluster:6379
  ↓
redis cluster (3 主 3 从)
  ├── master-0 (slot 0-5460)      ← slave-0
  ├── master-1 (slot 5461-10922)  ← slave-1
  └── master-2 (slot 10923-16383) ← slave-2
  ↓
persistentvolume (local-path)

二、前置条件

2.1 k8s 集群状态

2.2 存储要求

redis 的 statefulset 需要动态存储。必须提前配好 storageclass。

检查:

kubectl get storageclass

预期:至少有一个 storageclass,且设为 default。

如果没有,先装 local path provisioner:

kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.28/deploy/local-path-storage.
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

解析:

2.3 镜像网络要求

这是最容易踩坑的地方。 redis cluster 需要以下镜像:

镜像仓库
bitnami/redis-clusterdocker hub
bitnami/redis-exporterdocker hub(可选,监控用)

bitnami 从 2025 年 8 月 28 日起,把免费镜像从 docker hub 公共目录移除了。 直接拉 bitnami/redis-cluster 会返回 403 forbidden。

解决方案:从 bitnamilegacy 仓库拉旧版镜像,然后打标签。

# 从 daocloud 代理拉 bitnamilegacy 镜像
crictl pull docker.m.daocloud.io/bitnamilegacy/redis-cluster:8.2.1-debian-12-r0
# 打标签,让 containerd 认为本地有 bitnami/redis-cluster
ctr -n k8s.io images tag docker.m.daocloud.io/bitnamilegacy/redis-cluster:8.2.1-debian-12-r0 docker.io/bitnami/redis-cluster:8.2.1-debian-12-r0

解析:

2.4 配置 containerd 镜像加速

在每台节点上配置,解决所有 docker hub 镜像拉取问题。

编辑 /etc/containerd/config.,找到:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors]

在它下面加:

  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
    endpoint = [
      "https://docker.m.daocloud.io",
      "https://docker.mirrors.ustc.edu.cn"
    ]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
    endpoint = [
      "https://ghcr.nju.edu.cn"
    ]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]
    endpoint = [
      "https://quay.mirrors.ustc.edu.cn"
    ]

解析:

重启:

systemctl restart containerd
systemctl status containerd --no-pager | head -5

用 ansible 批量推:

---
- name: 配置 containerd 多镜像源
  hosts: k8s_cluster
  gather_facts: no
  become: no
  tasks:
    - name: 备份
      copy:
        src: /etc/containerd/config.
        dest: /etc/containerd/config..bak
        remote_src: yes
        force: no
    - name: 插入 docker.io 镜像加速
      blockinfile:
        path: /etc/containerd/config.
        marker: "# {mark} ansible managed mirrors"
        insertbefore: '\[plugins\."io\.containerd\.grpc\.v1\.cri"\.x509_key_pair_streaming\]'
        block: |
          [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
            endpoint = [
              "https://docker.m.daocloud.io",
              "https://docker.mirrors.ustc.edu.cn"
            ]
          [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
            endpoint = [
              "https://ghcr.nju.edu.cn"
            ]
          [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]
            endpoint = [
              "https://quay.mirrors.ustc.edu.cn"
            ]
    - name: 重启 containerd
      systemd:
        name: containerd
        state: restarted
        enabled: yes
    - name: 验证状态
      command: systemctl is-active containerd
      register: status
      changed_when: false
    - name: 输出
      debug:
        msg: "{{ inventory_hostname }}: containerd {{ status.stdout }}"

执行:

ansible-playbook -i inventory.ini containerd-mirror-multi.yml

三、安装 helm

3.1 确认 helm 可用

helm version

如果没有:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | 
hash -r
helm version

解析

四、下载 redis cluster chart

4.1 从 daocloud 代理拉取

不能用 helm repo add bitnami,因为 bitnami 的 chart 走 docker hub oci,国内不通。

直接用 daocloud 代理:

helm pull oci://docker.m.daocloud.io/bitnamicharts/redis-cluster --version 13.0.4

解析:

预期输出:

pulled: docker.m.daocloud.io/bitnamicharts/redis-cluster:13.0.4
digest: sha256:45229772bdde004303e5eaf12c1fff839811ba7f17d63e9fc6cbd8923d0531c2

下载后本地会有:redis-cluster-13.0.4.tgz

4.2 常见问题

问题:华为云源返回 401

error: installation failed: get "...swr.cn-north-4.myhuaweicloud.com...": response status code 401: denied: you may not login yet

原因:华为云的 docker hub 代理需要登录认证。

解决方案:用 daocloud,它免认证。

五、部署 redis cluster

5.1 创建命名空间

kubectl create namespace redis

解析:

5.2 安装 chart

helm install production-redis ./redis-cluster-13.0.4.tgz \
  --namespace redis \
  --set password=l48pw3luqopbkjyayffj \
  --set cluster.nodes=6 \
  --set cluster.replicas=1

逐项解析:

参数含义
production-redisrelease 名
./redis-cluster-13.0.4.tgz本地 chart 包
--namespace redis装到 redis 命名空间
--set password=...设置 redis 密码
--set cluster.nodes=6总共 6 个节点(3 主 3 从)
--set cluster.replicas=1每个主节点 1 个从节点

预期输出:

name: production-redis
last deployed: ...
namespace: redis
status: deployed
revision: 1

5.3 观察 pod 启动

kubectl get pods -n redis -w

按 ctrl+c 退出。

预期:6 个 pod 逐渐启动。

name                               ready   status    restarts   age
production-redis-redis-cluster-0   1/1     running   0          ...
production-redis-redis-cluster-1   1/1     running   0          ...
production-redis-redis-cluster-2   1/1     running   0          ...
production-redis-redis-cluster-3   1/1     running   0          ...
production-redis-redis-cluster-4   1/1     running   0          ...
production-redis-redis-cluster-5   1/1     running   0          ...

5.4 常见问题

问题一:pod 卡在 imagepullbackoff,拉 bitnami/redis-cluster 失败

原因:bitnami 从 2025 年 8 月 28 日起移除了 docker hub 公共目录的免费镜像,返回 403 forbidden。

排查:

kubectl describe pod -n redis production-redis-redis-cluster-0 | grep -a10 "events:"

解决方案:从 bitnamilegacy 拉镜像,打标签。

# 每台节点执行
crictl pull docker.m.daocloud.io/bitnamilegacy/redis-cluster:8.2.1-debian-12-r0
ctr -n k8s.io images tag docker.m.daocloud.io/bitnamilegacy/redis-cluster:8.2.1-debian-12-r0 docker.io/bitnami/redis-cluster:8.2.1-debian-12-r0

用 ansible 批量:

ansible k8s_cluster -i inventory.ini -m shell -a "
crictl pull docker.m.daocloud.io/bitnamilegacy/redis-cluster:8.2.1-debian-12-r0
ctr -n k8s.io images tag docker.m.daocloud.io/bitnamilegacy/redis-cluster:8.2.1-debian-12-r0 docker.io/bitnami/redis-cluster:8.2.1-debian-12-r0
" -b

然后删除卡住的 pod:

kubectl delete pod -n redis --all

问题二:pod 卡在 pending,报 failedscheduling

原因:pvc 绑不上,或节点不够。

排查:

kubectl get pvc -n redis
kubectl describe pod -n redis production-redis-redis-cluster-0 | tail -30

如果 pvc 是 pending,检查 provisioner:

kubectl get pods -n local-path-storage
kubectl logs -n local-path-storage -l app=local-path-provisioner --tail=50

问题三:pod 卡在 containercreating,报挂载失败

原因:pv 绑定失败。

排查:

kubectl describe pod -n redis production-redis-redis-cluster-0 | grep -a5 "volumes"
kubectl get pv | grep redis

六、验证集群

6.1 查看 pod 状态

kubectl get pods -n redis -o wide

预期:6 个 pod 全部 running 1/1。

6.2 取密码

export redis_password=$(kubectl get secret --namespace redis production-redis-redis-cluster -o jsonpath="{.data.redis-password}" | base64 -d)
echo $redis_password

解析:

保存这个密码。

6.3 查看集群节点

kubectl exec -it -n redis production-redis-redis-cluster-0 -- redis-cli -a $redis_password cluster nodes

解析:

预期输出:

<id1> 10.244.5.21:6379@16379 myself,master - 0 0 1 connected 0-5460
<id2> 10.244.0.7:6379@16379 master - 0 ... 2 connected 5461-10922
<id3> 10.244.6.17:6379@16379 master - 0 ... 3 connected 10923-16383
<id4> 10.244.5.20:6379@16379 slave <id1> ...
<id5> 10.244.1.7:6379@16379 slave <id2> ...
<id6> 10.244.4.7:6379@16379 slave <id3> ...

关注:

6.4 查看集群信息

kubectl exec -it -n redis production-redis-redis-cluster-0 -- redis-cli -a $redis_password cluster info

预期关键字段:

字段值含义
cluster_stateok集群正常
cluster_slots_assigned16384所有 slot 都分配了
cluster_known_nodes66 个节点都认识
cluster_size33 个分片

6.5 验证读写

kubectl exec -it -n redis production-redis-redis-cluster-0 -- redis-cli -c -a $redis_password set test-key "hello"
kubectl exec -it -n redis production-redis-redis-cluster-0 -- redis-cli -c -a $redis_password get test-key

解析:

预期:

6.6 高可用验证

测试:删掉一个 master,看自动故障转移

第一步:找到 master 对应的 pod

kubectl exec -it -n redis production-redis-redis-cluster-0 -- redis-cli -a $redis_password cluster nodes | grep myself

出里 myself,master 那一行就是当前 pod 的角色。记下它的 ip。

第二步:找到 ip 对应的 pod 名

kubectl get pods -n redis -o wide

第三步:删掉那个 pod

kubectl delete pod -n redis <master-pod-name>

第四步:观察

kubectl get pods -n redis -w

预期:

第五步:验证恢复

kubectl exec -it -n redis production-redis-redis-cluster-1 -- redis-cli -a $redis_password cluster nodes

预期:6 个节点重新在线,角色可能互换,但 slot 分配仍然完整。

七、应用接入

7.1 连接信息

在集群内部:

用途地址
redis clusterproduction-redis-redis-cluster.redis.svc.cluster.local:6379

简写(同命名空间):

production-redis-redis-cluster:6379

跨命名空间:

production-redis-redis-cluster.redis.svc.cluster.local:6379

密码:从 secret 取。

7.2 应用配置示例

python (redis-py):

from redis.cluster import rediscluster
client = rediscluster(
    host='production-redis-redis-cluster.redis',
    port=6379,
    password='<密码>',
    decode_responses=true
)

node.js (ioredis):

const redis = require('ioredis');
const cluster = new redis.cluster([
  { host: 'production-redis-redis-cluster.redis', port: 6379 }
], {
  redisoptions: {
    password: '<密码>'
  }
});

java (lettuce):

redisclusterclient client = redisclusterclient.create(
    "redis://:<密码>@production-redis-redis-cluster.redis:6379"
);

go (go-redis):

import "github.com/redis/go-redis/v9"
rdb := redis.newclusterclient(&redis.clusteroptions{
    addrs:    []string{"production-redis-redis-cluster.redis:6379"},
    password: "<密码>",
})

7.3 部署后端服务到 k8s

apiversion: apps/v1
kind: deployment
metadata:
  name: my-backend
  namespace: default
spec:
  replicas: 2
  selector:
    matchlabels:
      app: my-backend
  template:
    metadata:
      labels:
        app: my-backend
    spec:
      containers:
        - name: my-backend
          image: my-backend:latest
          ports:
            - containerport: 8080
          env:
            - name: redis_host
              value: "production-redis-redis-cluster.redis"
            - name: redis_port
              value: "6379"
            - name: redis_password
              valuefrom:
                secretkeyref:
                  name: production-redis-redis-cluster
                  key: redis-password

解析:

7.4 验证连通性

进后端 pod:

kubectl exec -it <backend-pod> -- sh

测试端口:

nc -zv production-redis-redis-cluster.redis 6379

解析:

八、常用操作

8.1 查看集群状态

kubectl get pods -n redis
kubectl get pvc -n redis
kubectl get svc -n redis

8.2 查看日志

kubectl logs -n redis production-redis-redis-cluster-0 --tail=100

8.3 连接 redis

kubectl exec -it -n redis production-redis-redis-cluster-0 -- redis-cli -c -a $redis_password

8.4 扩容集群

增加节点:

helm upgrade production-redis ./redis-cluster-13.0.4.tgz \
  --namespace redis \
  --set password=l48pw3luqopbkjyayffj \
  --set cluster.nodes=8 \
  --set cluster.replicas=1

解析:

8.5 删除集群

helm uninstall production-redis -n redis
kubectl delete pvc -n redis -l app.kubernetes.io/instance=production-redis
kubectl delete namespace redis

警告:删除 pvc 会删除所有数据,操作前先备份。

九、架构总结

9.1 组件清单

组件数量作用
redis pod63 主 3 从
statefulset1管理 redis pod
pvc6每个 pod 一块存储
service2集群内部通信和客户端入口
secret1redis 密码

9.2 端口速查

端口用途
6379redis 客户端连接
16379redis cluster 总线(集群内部通信)

9.3 高可用机制

故障场景影响恢复方式
从节点故障无影响主节点继续服务,从节点重建后重新同步
主节点故障该分片短暂不可用从节点自动提升为主,slot 自动接管
多个主节点故障部分 slot 不可用如果超过半数主节点故障,集群停止服务

9.4 已知隐患

隐患影响解决方案
节点集中在 q5、q6节点故障影响多个 pod加工作节点,或允许调度到控制平面
local path 存储pod 漂移数据丢失换 nfs / ceph / longhorn
bitnami 免费镜像移除无法拉取最新镜像用 bitnamilegacy 旧版镜像
未配备份数据无法恢复用 redis-cli --rdb 或 redis 持久化

十、总结

这套 redis cluster 基于 bitnami helm chart,提供了:

部署中最容易踩的坑:

  1. bitnami 免费镜像移除:必须用 bitnamilegacy 旧版镜像,并打标签。
  2. docker hub 访问超时:必须配 containerd 镜像加速。
  3. helm chart 拉取超时:用 daocloud 的 oci 代理。

到此这篇关于redis cluster 高可用集群部署方案详解的文章就介绍到这了,更多相关redis cluster 集群部署内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

赞 (0)

您想发表意见!!点此发布评论

推荐阅读

Redis与ZooKeeper分布式锁实现原理与实战对比

09-29

Redis持久化与事务机制原理、配置与避坑指南

09-30

Redis 持久化与事务:RDB、AOF、MULTI/EXEC 与 WATCH 全解析

09-30

Redis连接断开后实现自动重连的操作过程

09-30

Nginx+Lua+Redis实现动态封禁IP的几种方法

09-30

在Ubuntu上安装和使用Composer流程步骤

09-30

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论