Redis集群恢复后如何重新分配槽位?

以下是针对Redis集群恢复后重新分配槽位的标准化操作指南,结合生产环境最佳实践整理,包含不同场景下的详细步骤和注意事项:


一、槽位分配核心原理

Redis集群通过**哈希槽(Hash Slot)**实现数据分片,共16384个槽位,分配规则如下:

  1. 槽位分布机制

    • 每个主节点负责连续的槽位范围(如节点A负责0-5460,节点B负责5461-10922)
    • 槽位分配采用区间形式,例如节点A的槽位范围可能显示为0-500,1000-2000(非连续分配时)
    • 从节点不直接存储槽位数据,仅作为主节点的热备副本
  2. 客户端路由逻辑

    • 客户端通过CRC16(key) % 16384计算键的槽位值
    • 当访问的键不属于当前节点时,会返回MOVED重定向响应
    • 智能客户端(如Lettuce)会缓存slot-node映射关系

二、恢复后重新分配槽位的场景

场景1:部分节点恢复(需重新分配)

典型故障现象

  • redis-cli cluster nodes显示部分节点状态为failhandshake
  • 槽位状态出现importing/migrating标志
  • 集群状态为cluster_state:fail(通过CLUSTER INFO查看)

恢复操作流程

  1. 先通过CLUSTER FAILOVER命令恢复故障节点
  2. 检查各节点数据一致性:redis-cli --cluster check <host>:<port>
  3. 对数据不一致的槽位执行强制修复:redis-cli --cluster fix <host>:<port>
场景2:集群扩容后(需调整分配)

负载均衡策略

  • 新增节点后建议采用渐进式迁移(每次迁移约5%的槽位)
  • 计算公式:每个节点槽位数 ≈ 16384 / 主节点数量 ± 允许偏差值
  • 监控指标:各节点内存使用率差异应<15%,QPS差异<20%

三、重新分配槽位的操作步骤

方法1:使用redis-cli --cluster reshard命令(推荐)

完整交互示例

$ redis-cli --cluster reshard 192.168.1.101:7001
>>> Performing Cluster Check (using node 192.168.1.101:7001)
M: 1f2b3c4d... 192.168.1.101:7001 slots:[0-5460] (5461 slots) master
M: 5e6f7g8h... 192.168.1.102:7001 slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.

How many slots do you want to move (from 1 to 16384)? 1000
What is the receiving node ID? 1f2b3c4d...  # 目标节点ID
Please enter all the source node IDs.
 Type 'all' to use all the nodes as source nodes.
 Type 'done' once you entered all the source nodes.
Source node #1: 5e6f7g8h...  # 源节点ID
Source node #2: done
Do you want to proceed with the proposed reshard plan (yes/no)? yes

关键参数说明

  • --cluster-slots:指定单次迁移槽位数量(建议≤500)
  • --cluster-timeout:设置迁移超时时间(默认60秒)
  • --cluster-pipeline:批量迁移键数量(默认10)
方法2:手动迁移槽位(精细控制)

分步操作示例

  1. 准备阶段

    # 在目标节点设置导入状态
    redis-cli -h 192.168.1.101 -p 7001 CLUSTER SETSLOT 5461 IMPORTING 5e6f7g8h...
    
    # 在源节点设置迁移状态
    redis-cli -h 192.168.1.102 -p 7001 CLUSTER SETSLOT 5461 MIGRATING 1f2b3c4d...
    

  2. 数据迁移阶段

    # 批量迁移该槽位的键(每次100个)
    redis-cli -h 192.168.1.102 -p 7001 CLUSTER GETKEYSINSLOT 5461 100 | \
    xargs -L 100 redis-cli -h 192.168.1.102 -p 7001 MIGRATE 192.168.1.101 7001 "" 0 5000 KEYS
    

  3. 完成阶段

    # 通知所有节点更新槽位映射
    redis-cli -h 192.168.1.101 -p 7001 CLUSTER SETSLOT 5461 NODE 1f2b3c4d...
    


四、自动化槽位分配脚本增强版

#!/bin/bash
REDIS_NODES="192.168.1.101:7001 192.168.1.102:7001 192.168.1.103:7001"
TARGET_MEMORY_USAGE=70  # 目标内存使用率阈值

# 动态计算需要迁移的槽位数
calculate_slots() {
    local node=$1
    local used_mem=$(redis-cli -h ${node%:*} -p ${node#*:} INFO MEMORY | grep used_memory: | awk -F: '{print $2}')
    local max_mem=$(redis-cli -h ${node%:*} -p ${node#*:} CONFIG GET maxmemory | tail -1)
    local usage=$((used_mem*100/max_mem))
    
    if [ $usage -gt $TARGET_MEMORY_USAGE ]; then
        echo $(( (usage - TARGET_MEMORY_USAGE) * 100 ))
    else
        echo 0
    fi
}

for node in $REDIS_NODES; do
    slots_to_move=$(calculate_slots $node)
    if [ $slots_to_move -gt 0 ]; then
        redis-cli --cluster reshard $node \
            --cluster-from $(redis-cli -c -h ${node%:*} -p ${node#*:} CLUSTER NODES | grep master | awk '{print $1}') \
            --cluster-to $(redis-cli -c -h ${node%:*} -p ${node#*:} CLUSTER NODES | grep master | grep -v ${node%:*} | head -1 | awk '{print $1}') \
            --cluster-slots $slots_to_move \
            --cluster-yes
    fi
done


五、生产环境关键注意事项

  1. 迁移性能优化

    • 调整repl-timeout(默认60秒)避免超时中断
    • 增加cluster-node-timeout(默认15秒)应对网络延迟
    • 禁用THP:echo never > /sys/kernel/mm/transparent_hugepage/enabled
  2. 监控指标清单

    watch -n 1 "redis-cli -h 192.168.1.101 -p 7001 CLUSTER INFO | grep -E 'cluster_slots_assigned|cluster_state'"
    

  3. 异常处理方案

    • 槽位冲突:执行CLUSTER FLUSHSLOTS重置状态
    • 迁移卡死:重启对应节点触发拓扑重建
    • 数据校验:使用redis-check-rdb工具验证备份文件

六、版本兼容性矩阵

操作命令Redis 5.xRedis 6.xRedis 7.x
CLUSTER ADDSLOTS支持支持支持
--cluster reshard部分支持完全支持完全支持
MIGRATE AUTH不支持支持支持

建议在操作前通过redis-server -v确认集群版本一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值