Skip to content

Redis 单实例到集群迁移

迁移前规划

何时迁移到 Redis Cluster

  • 扩展需求:当单个 Redis 实例达到内存或性能极限时
  • 高可用性:当您需要内置的故障转移和冗余机制时
  • 吞吐量要求:当您需要将读写操作分布到多个节点时
  • 容错能力:当您需要防止单个节点故障时

迁移选项

  1. 离线迁移:停止 Redis,迁移数据,以集群模式重启(适用于小型数据集)
  2. 在线迁移:Redis 运行时迁移数据(适用于生产环境)
  3. 双写迁移:迁移期间同时写入单实例和集群(最小化停机时间)

集群设计

  1. 节点数量:最少 6 个节点(3 个主节点,3 个从节点)
  2. 内存分配:总内存分配到各个主节点
  3. 复制因子:通常每个主节点配置 1 个从节点
  4. 槽位分布:由 Redis Cluster 自动分配
  5. 硬件要求:与单实例相同或更高

环境准备

  1. 准备服务器:为集群节点准备服务器
  2. 安装 Redis:安装相同或兼容版本的 Redis
  3. 配置网络:确保所有节点可以相互通信
  4. 设置监控:为新集群节点配置监控
  5. 准备备份:创建单 Redis 实例的完整备份

应用兼容性

  1. 检查客户端兼容性:确保客户端支持 Redis Cluster
  2. 更新客户端配置:修改客户端代码以使用集群模式
  3. 在测试环境验证:在测试环境中测试迁移过程
  4. 规划停机时间:估算并告知相关人员预期的停机时间

迁移过程

方案 1:离线迁移

步骤

  1. 备份单实例

    bash
    redis-cli bgsave
    cp /var/lib/redis/dump.rdb /backup/
  2. 停止单实例

    bash
    sudo systemctl stop redis-server
  3. 配置集群节点: 编辑每个节点的 redis.conf 文件:

    txt
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 15000
    port 6379
    daemonize yes
    pidfile /var/run/redis_6379.pid
    logfile /var/log/redis/redis_6379.log
    dir /var/lib/redis
  4. 启动所有集群节点

    bash
    redis-server /etc/redis/redis.conf
  5. 创建集群

    bash
    redis-cli --cluster create node1:6379 node2:6379 node3:6379 node4:6379 node5:6379 node6:6379 --cluster-replicas 1
  6. 恢复数据到各个主节点

    • 将 RDB 文件数据分配到各个主节点(手动或使用脚本)
    • 或使用 redis-cli --cluster add-node 命令并指定 --cluster-slave 选项
  7. 启动集群

    bash
    redis-cli --cluster check node1:6379
  8. 更新应用配置:将应用指向新集群

优缺点

优点

  • 流程简单
  • 无数据一致性问题

缺点

  • 需要停机时间
  • 对于大型数据集,手动分配数据可能复杂

方案 2:使用 Redis-cli 在线迁移

步骤

  1. 搭建空 Redis 集群:按照离线迁移的步骤 3-5 执行

  2. 使用 redis-cli --cluster import

    bash
    redis-cli --cluster import cluster-node1:6379 --cluster-from single-instance:6379 --cluster-copy
    • --cluster-copy:复制键而不是移动它们
    • --cluster-replace:替换集群中已存在的键
  3. 验证数据迁移

    bash
    # 比较键数量
    redis-cli -h single-instance keys "*" | wc -l
    redis-cli -c -h cluster-node1 keys "*" | wc -l
  4. 切换应用到集群:更新应用配置

  5. 监控集群性能:检查是否有任何问题

优缺点

优点

  • 最小化停机时间
  • 自动分配数据

缺点

  • 迁移期间可能影响性能
  • 需要足够的网络带宽

方案 3:双写迁移

步骤

  1. 搭建 Redis 集群:按照离线迁移的步骤 3-5 执行

  2. 修改应用以支持双写

    • 更新应用代码,同时写入单实例和集群
    • 初始阶段继续从单实例读取
  3. 同步现有数据

    • 使用 redis-cli --cluster import 或自定义脚本同步现有数据
    • 验证单实例和集群之间的数据一致性
  4. 逐步将读取切换到集群

    • 更新应用代码,从集群读取数据
    • 监控是否有任何不一致
  5. 停止写入单实例

    • 一旦所有读取成功切换到集群
    • 更新应用代码,仅写入集群
  6. 停用单实例

    • 验证集群运行正常
    • 关闭单个 Redis 实例

优缺点

优点

  • 几乎零停机
  • 数据安全性高
  • 允许逐步过渡

缺点

  • 应用修改复杂
  • 迁移周期较长
  • 需要仔细监控

迁移后验证

集群健康检查

bash
# 检查集群状态
redis-cli -c cluster info

# 检查节点状态
redis-cli -c cluster nodes

# 检查槽位分布
redis-cli -c cluster slots

数据一致性验证

bash
# 比较键数量
redis-cli -h single-instance keys "*" | wc -l
redis-cli -c -h cluster-node1 keys "*" | wc -l

# 验证特定键
redis-cli -h single-instance get key1
redis-cli -c -h cluster-node1 get key1

# 使用 redis-check-rdb 验证 RDB 文件
redis-check-rdb /var/lib/redis/dump.rdb

性能监控

  • 内存使用:确保内存在节点间均匀分布
  • CPU 使用:监控是否有 CPU 峰值
  • 网络流量:检查节点间是否有过多的网络使用
  • 命令延迟:验证延迟在可接受范围内
  • 连接数:确保连接在集群节点间分布

应用验证

  • 功能测试:测试所有使用 Redis 的应用功能
  • 性能测试:验证应用性能符合要求
  • 错误监控:检查应用日志中是否有 Redis 相关错误
  • 负载测试:在峰值负载条件下测试应用

迁移后优化

槽位平衡

bash
# 检查槽位分布
redis-cli -c cluster slots

# 如有需要,重新平衡槽位
redis-cli --cluster rebalance cluster-node1:6379 --cluster-use-empty-masters

复制优化

  • 监控复制延迟:确保从节点与主节点同步
  • 配置从节点优先级:为故障转移设置适当的优先级
  • 启用从节点读取:如有需要,允许应用从从节点读取

安全加固

  • 更新防火墙规则:限制对集群节点的访问
  • 设置强密码:配置 requirepass 和 masterauth
  • 启用 SSL/TLS:如果尚未启用
  • 配置 ACL:实现细粒度访问控制

监控和告警

  • 设置集群特定告警:监控集群状态、节点故障、槽位迁移
  • 配置仪表盘:为集群指标创建 Grafana 仪表盘
  • 实现日志监控:监控 Redis 集群日志中的错误

常见问题及解决方案

槽位迁移失败

问题:在线迁移期间槽位迁移失败

解决方案

  • 检查节点间的网络连接
  • 确保目标节点有足够内存
  • 验证 Redis 版本兼容性
  • 如果键已存在,使用 --cluster-replace 选项

数据不一致

问题:迁移后单实例和集群之间的数据不一致

解决方案

  • 对关键数据使用双写方案
  • 切换应用前验证数据一致性
  • 实现数据验证检查
  • 使用 Redis Cluster 内置的一致性检查

应用连接问题

问题:应用无法连接到 Redis 集群

解决方案

  • 验证客户端与 Redis Cluster 兼容性
  • 检查客户端是否支持集群模式
  • 更新客户端配置,包含多个集群节点
  • 确保防火墙规则允许客户端连接

性能下降

问题:迁移到集群后性能下降

解决方案

  • 检查槽位分布并根据需要重新平衡
  • 优化应用代码,高效使用集群
  • 确保网络配置正确
  • 考虑增加集群节点数量

迁移最佳实践

彻底规划

  • 记录整个迁移过程
  • 在测试环境中测试
  • 创建回滚计划
  • 估算迁移时间并与相关人员沟通

备份所有数据

  • 迁移前创建完整备份
  • 测试备份恢复过程
  • 将备份存储在安全的异地位置

持续监控

  • 迁移各阶段都进行监控
  • 为关键指标设置告警
  • 准备好回滚计划

从小规模开始

  • 先迁移非关键数据
  • 逐步增加集群流量
  • 每一步都监控性能

使用自动化

  • 自动化集群部署
  • 使用脚本进行数据验证
  • 实现自动化监控

常见问题(FAQ)

Q1:Redis 单实例到集群迁移需要多长时间?

A1:迁移时间取决于以下因素:

  • 数据集大小:数据集越大,迁移时间越长
  • 迁移方法:对于小型数据集,离线迁移更快;对于大型数据集,在线迁移更适合
  • 网络带宽:更快的网络减少迁移时间
  • 系统资源:更强大的服务器处理迁移更快

Q2:我可以从旧版 Redis 迁移到集群吗?

A2:可以,但需确保兼容性:

  • Redis Cluster 需要 Redis 3.0 或更高版本
  • 为获得最佳效果,单实例和集群使用相同的 Redis 版本
  • 检查发布说明,了解任何版本特定的迁移问题

Q3:如何处理太大而无法放入单个槽位的键?

A3:Redis Cluster 使用哈希标签将相关键分组到同一槽位。对于大键:

  • 尽可能使用较小的键并拆分数据
  • 对相关键使用哈希标签:{user:123}:profile{user:123}:settings
  • 考虑使用 Redis 模块处理大型数据结构

Q4:如果迁移失败,回滚计划是什么?

A4:回滚步骤取决于迁移方法:

  • 离线迁移:从备份恢复并重启单实例
  • 在线迁移:将应用切换回单实例
  • 双写迁移:停止写入集群,继续使用单实例

Q5:迁移后如何监控 Redis Cluster?

A5:监控以下关键指标:

  • 集群状态和健康状况
  • 节点可用性和复制延迟
  • 槽位分布和迁移
  • 节点间的内存使用
  • 命令延迟和吞吐量
  • 节点间的网络流量

Q6:迁移后可以向集群添加更多节点吗?

A6:是的,迁移后可以轻松扩展 Redis Cluster:

  • 添加新的主节点并重新平衡槽位
  • 添加从节点以提高容错能力
  • 使用 redis-cli --cluster add-node 命令
  • 示例:redis-cli --cluster add-node new-node:6379 existing-node:6379