暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Linux Redis 运维实战:Redis Cluster 集群部署与管理

150

Linux Redis 运维实战:Redis Cluster 集群部署与管理

前言

Redis Cluster 是 Redis 提供的分布式解决方案,旨在满足大规模、高并发场景下的数据存储和高可用需求。相比主从复制和哨兵模式,Redis Cluster 通过数据分片和自动故障转移实现了更高的扩展性和可靠性。在 Linux 环境下,Redis Cluster 的部署与运维涉及多节点配置、槽分配、扩容缩容、监控告警和故障恢复等复杂任务。

一、Redis Cluster 原理

1.1 Redis Cluster 的工作机制

Redis Cluster 通过数据分片(sharding)将键空间划分为 16384 个槽(slot),由多个节点共同管理。其核心机制包括:

  1. 数据分片
    • 键通过 CRC16 算法映射到 0-16383 的槽。
    • 每个节点负责一部分槽,数据分布在不同节点上。
  2. 节点通信
    • 节点通过 Gossip 协议交换状态信息,维护集群拓扑。
    • 节点分为主节点(Master)和从节点(Slave),从节点为主节点提供备份。
  3. 故障转移
    • 主节点故障时,从节点自动升级为主节点,接管槽。
    • 集群通过多数派(majority)机制确认故障。
  4. 客户端交互
    • 客户端通过集群协议(如 MOVED 重定向)访问正确节点。
    • 支持智能客户端(如 JedisCluster、Lettuce)自动处理槽映射。

1.2 Redis Cluster 的特点

  • 分布式存储:数据分片支持大规模数据存储。
  • 高可用:主从节点自动故障转移。
  • 线性扩展:支持动态添加或移除节点。
  • 去中心化:无单点依赖,所有节点对等。

1.3 运维视角的挑战

  • 部署复杂性:多节点配置和槽分配需精确规划。
  • 数据一致性:故障转移和节点变更可能导致数据丢失。
  • 性能优化:槽分布不均或热点键可能引发性能瓶颈。
  • 监控需求:需实时监控槽状态、节点健康和集群一致性。

二、Redis Cluster 的部署与配置

2.1 环境准备

以下以 CentOS 8 为例,部署一个 6 节点(3 主 3 从)Redis Cluster:

  • 节点信息

    • 主节点 1:192.168.1.100:6379
    • 主节点 2:192.168.1.101:6379
    • 主节点 3:192.168.1.102:6379
    • 从节点 1:192.168.1.103:6379
    • 从节点 2:192.168.1.104:6379
    • 从节点 3:192.168.1.105:6379
  • 前提

    • Redis 7.0.12 已安装(参考专栏第 1 篇)。

    • 防火墙允许 6379 和 16379(Gossip 协议端口):

      sudo firewall-cmd --permanent --add-port={6379,16379}/tcp
      sudo firewall-cmd --reload

    • 每节点磁盘空间 > 10GB,内存 > 4GB。

2.2 节点配置

为每个节点创建配置文件 etc/redis/redis.conf(以 192.168.1.100 为例):

bind 192.168.1.100
port 6379
requirepass your_secure_password
masterauth your_secure_password
dir var/redis/data/
logfile var/log/redis/redis.log
maxmemory 4gb
maxmemory-policy allkeys-lru
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000

  • 关键参数
    • cluster-enabled:启用集群模式。
    • cluster-config-file:存储集群拓扑信息,自动生成。
    • cluster-node-timeout:节点超时时间,影响故障检测速度。
    • requirepass 和 masterauth:设置密码,增强安全性。

其他节点配置类似,仅修改 bind 为对应 IP。启动所有节点:

sudo systemctl start redis

2.3 创建集群

使用 redis-cli 创建集群:

redis-cli --cluster create \
  192.168.1.100:6379 192.168.1.101:6379 192.168.1.102:6379 \
  192.168.1.103:6379 192.168.1.104:6379 192.168.1.105:6379 \
  --cluster-replicas 1 -a your_secure_password

  • 参数说明
    • --cluster-replicas 1:每个主节点分配一个从节点。
    • -a:指定密码。
  • 输出:确认槽分配(每个主节点约 5461 个槽)并同意创建。

2.4 验证集群

  1. 检查集群状态

    redis-cli -h 192.168.1.100 -p 6379 -a your_secure_password cluster info

    输出示例:

    cluster_state:ok
    cluster_slots_assigned:16384
    cluster_slots_ok:16384
    cluster_known_nodes:6

  2. 查看节点信息

    redis-cli -h 192.168.1.100 -p 6379 -a your_secure_password cluster nodes

    输出示例:

    node1 192.168.1.100:6379@16379 master - 0 1634567890 1 connected 0-5460
    node2 192.168.1.101:6379@16379 master - 0 1634567890 2 connected 5461-10922
    node3 192.168.1.102:6379@16379 master - 0 1634567890 3 connected 10923-16383
    node4 192.168.1.103:6379@16379 slave node1 0 1634567890 4 connected
    node5 192.168.1.104:6379@16379 slave node2 0 1634567890 5 connected
    node6 192.168.1.105:6379@16379 slave node3 0 1634567890 6 connected

  3. 测试数据存取

    redis-cli -c -h 192.168.1.100 -p 6379 -a your_secure_password
    > SET key1 value1
    > GET key1

    -c 启用集群模式,自动重定向到正确节点。

2.5 优化配置

  • 节点超时:调整 cluster-node-timeout(如 10 秒)加速故障检测:

    cluster-node-timeout 10000

  • 复制缓冲区:增大 repl-backlog-size 减少全量同步:

    repl-backlog-size 50mb

  • 无盘复制:启用 repl-diskless-sync 优化高带宽场景:

    repl-diskless-sync yes

三、集群扩展与缩容

3.1 扩展集群(添加节点)

  1. 添加新主节点(如 192.168.1.106:6379):

    • 配置与现有节点一致,启动 Redis:

      sudo systemctl start redis

    • 将新节点加入集群:

      redis-cli --cluster add-node 192.168.1.106:6379 192.168.1.100:6379 -a your_secure_password

  2. 重新分配槽

    • 使用 redis-cli --cluster reshard:

      redis-cli --cluster reshard 192.168.1.100:6379 -a your_secure_password

    • 输入槽数量(如 4096,约 1/4 总槽数),选择源节点和新节点。

  3. 添加从节点(如 192.168.1.107:6379):

    • 加入集群:

      redis-cli --cluster add-node 192.168.1.107:6379 192.168.1.100:6379 -a your_secure_password

    • 设置为主节点的从节点:

      redis-cli -h 192.168.1.107 -p 6379 -a your_secure_password CLUSTER REPLICATE <master-node-id>

3.2 缩容集群(移除节点)

  1. 移除从节点

    • 执行:

      redis-cli --cluster del-node 192.168.1.107:6379 <node-id> -a your_secure_password

  2. 移除主节点

    • 将槽迁移到其他主节点:

      redis-cli --cluster reshard 192.168.1.100:6379 --cluster-from <node-id> --cluster-to <target-node-id> --cluster-slots 5461 -a your_secure_password

    • 删除节点:

      redis-cli --cluster del-node 192.168.1.106:6379 <node-id> -a your_secure_password

3.3 运维实践

  • 槽分配规划:确保槽均匀分布,避免单节点负载过高。
  • 备份数据:扩容/缩容前备份 RDB 和 AOF 文件。
  • 测试切换:模拟节点故障,验证槽迁移和数据一致性。

四、监控与告警

4.1 监控关键指标

使用 CLUSTER INFO 和 INFO 命令监控集群状态:

  • 集群状态
    • cluster_state:ok 表示集群正常。
    • cluster_slots_assigned:已分配槽数(应为 16384)。
    • cluster_known_nodes:集群节点总数。
  • 节点状态
    • role:主节点或从节点。
    • connected_slaves:主节点的从节点数。
    • repl_offset:复制偏移量。

4.2 Prometheus + Redis Exporter

  • 部署 Redis Exporter

    docker run -d --name redis-exporter -p 9121:9121 oliver006/redis_exporter \
      --redis.addr=redis://192.168.1.100:6379,redis://192.168.1.101:6379,redis://192.168.1.102:6379 \
      --redis.password=your_secure_password

  • Prometheus 配置

    scrape_configs:
      - job_name: 'redis-cluster'
        static_configs:
          - targets: ['192.168.1.100:9121', '192.168.1.101:9121', '192.168.1.102:9121']

  • 关键指标

    • redis_cluster_slots_assigned:已分配槽数。
    • redis_cluster_state:集群状态(1=ok,0=fail)。
    • redis_connected_slaves:从节点连接数。

4.3 告警规则

Prometheus 告警规则示例:

groups:
- name: redis-cluster
  rules:
  - alert: ClusterStateFail
    expr: redis_cluster_state == 0
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "Redis Cluster {{ $labels.instance }} state failed"
  - alert: SlotUnassigned
    expr: redis_cluster_slots_assigned < 16384
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Redis Cluster {{ $labels.instance }} has unassigned slots"

4.4 自动化监控脚本

  • Python 脚本示例:监控集群状态并发送告警。

    import redis
    import smtplib
    from email.mime.text import MIMEText

    r = redis.Redis(host='192.168.1.100', port=6379, password='your_secure_password')
    info = r.cluster_info()
    if info['cluster_state'] != 'ok':
        msg = MIMEText(f'Redis Cluster state: {info["cluster_state"]}')
        msg['Subject'] = 'Redis Cluster Alert'
        msg['From'] = 'admin@example.com'
        msg['To'] = 'ops@example.com'
        with smtplib.SMTP('smtp.example.com'as smtp:
            smtp.send_message(msg)

  • 运维实践

    • 定期运行脚本(如 cron 每 5 分钟)。
    • 结合 Grafana 可视化槽分布和节点状态。

五、故障排查与恢复

5.1 常见故障及排查

  1. 集群状态异常(cluster_state: fail)

    • 重新分配槽:

      redis-cli --cluster fix 192.168.1.100:6379 -a your_secure_password

    • 重启故障节点。

    • 检查 CLUSTER INFO 中的 cluster_slots_assigned。
    • 查看节点日志:/var/log/redis/redis.log。
    • 原因:槽未全部分配、节点宕机。

    • 排查

    • 解决

  2. 节点故障

    • 若主节点故障,等待从节点自动升级。

    • 若从节点故障,重新加入集群:

      redis-cli -h 192.168.1.103 -p 6379 -a your_secure_password CLUSTER REPLICATE <master-node-id>

    • 检查 CLUSTER NODES 的节点状态(fail 标志)。
    • 验证复制偏移量:INFO REPLICATION。
    • 原因:主节点宕机、从节点同步失败。

    • 排查

    • 解决

  3. 客户端重定向错误

    • 原因:客户端未正确处理 MOVED 或 ASK 重定向。
    • 排查:检查客户端日志,确认是否使用集群模式客户端。
    • 解决:升级客户端为 JedisCluster 或 Lettuce。

5.2 故障恢复

  • 主节点宕机

    1. 等待从节点自动升级为主节点(CLUSTER NODES 确认)。

    2. 修复原主节点,加入集群作为从节点:

      redis-cli -h 192.168.1.100 -p 6379 -a your_secure_password CLUSTER REPLICATE <new-master-node-id>

  • 槽迁移失败

    1. 检查槽状态:CLUSTER SLOTS。

    2. 手动修复:

      redis-cli --cluster fix 192.168.1.100:6379 -a your_secure_password

  • 运维实践

    • 定期备份集群配置文件(nodes-6379.conf)。
    • 模拟节点故障,测试故障转移时间。

六、运维案例:集群优化与故障恢复

6.1 场景描述

某 Redis Cluster(6 节点,32GB 内存,Redis 7.0)在高峰期出现槽分配不均,部分主节点 QPS 达 100k/s,集群状态变为 fail,客户端请求失败率达 15%。

6.2 排查步骤

  1. 检查集群状态
    • CLUSTER INFO 显示 cluster_state: fail,cluster_slots_assigned: 16000。
    • CLUSTER SLOTS 发现主节点 192.168.1.100 分配 8000 槽,其他节点约 4000 槽。
  2. 分析日志
    • 主节点日志显示高负载,CPU 占用 95%。
    • 从节点日志提示同步延迟达 10MB。
  3. 监控数据
    • Prometheus 显示 redis_cluster_slots_assigned 未达 16384。
    • redis_connected_slaves 正常,但热点键集中在主节点 192.168.1.100。

6.3 优化措施

  • 重新分配槽

    • 执行:

      redis-cli --cluster reshard 192.168.1.100:6379 --cluster-from 192.168.1.100:6379 --cluster-to 192.168.1.101:6379 --cluster-slots 2000 -a your_secure_password

    • 确保每主节点约 5461 槽。

  • 优化热点键

    • 使用 redis-cli --hotkeys 识别热点键。
    • 通过客户端分片(如 Twemproxy)分散热点键访问。
  • 调整参数

    • 降低 cluster-node-timeout:

      cluster-node-timeout 5000

    • 增大 repl-backlog-size:

      repl-backlog-size 100mb

  • 增强监控

    • 配置 Prometheus 告警,监控 redis_cluster_state 和 redis_cluster_slots_assigned。
    • 添加 Grafana 仪表盘,展示槽分布和节点负载。

6.4 优化结果

  • 集群状态恢复 ok,槽分配均匀。
  • 主节点 QPS 均衡至 50k/s,CPU 占用降至 70%。
  • 客户端请求失败率降至 1%,系统稳定性增强。

七、总结与展望

本篇讲解了 Redis Cluster 的原理、部署步骤、扩展缩容、监控与告警、故障排查与恢复实践。Redis Cluster 通过数据分片和高可用设计满足了大规模场景需求,运维工程师需掌握槽管理、节点扩展和故障处理技巧。

文章转载自戏说数据那点事,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论