Redis分片集群

Redis分片集群

部署

三主三从配置

services:
  redis-node-1:
    image: docker.io/redis:5.0.5
    container_name: redis-node-1
    command: redis-server 
      --cluster-enabled yes 
      --cluster-config-file nodes.conf 
      --cluster-node-timeout 5000 
      --cluster-migration-barrier 1
      --cluster-require-full-coverage no
      --appendonly yes 
      --port 17001
      --requirepass moxigame
      --masterauth moxigame
    network_mode: host
    volumes:
      - ./data/node-1:/data
    restart: unless-stopped

  redis-node-2:
    image: docker.io/redis:5.0.5
    container_name: redis-node-2
    command: redis-server 
      --cluster-enabled yes 
      --cluster-config-file nodes.conf 
      --cluster-node-timeout 5000 
      --cluster-migration-barrier 1
      --cluster-require-full-coverage no
      --appendonly yes 
      --port 17002
      --requirepass moxigame
      --masterauth moxigame
    network_mode: host
    volumes:
      - ./data/node-2:/data
    restart: unless-stopped

  redis-node-3:
    image: docker.io/redis:5.0.5
    container_name: redis-node-3
    command: redis-server 
      --cluster-enabled yes 
      --cluster-config-file nodes.conf 
      --cluster-node-timeout 5000 
      --cluster-migration-barrier 1
      --cluster-require-full-coverage no
      --appendonly yes 
      --port 17003
      --requirepass moxigame
      --masterauth moxigame
    network_mode: host
    volumes:
      - ./data/node-3:/data
    restart: unless-stopped
    
  redis-node-4:
    image: docker.io/redis:5.0.5
    container_name: redis-node-4
    command: redis-server 
      --cluster-enabled yes 
      --cluster-config-file nodes.conf 
      --cluster-node-timeout 5000 
      --cluster-migration-barrier 1
      --cluster-require-full-coverage no
      --appendonly yes 
      --port 17004
      --requirepass moxigame
      --masterauth moxigame
    network_mode: host
    volumes:
      - ./data/node-4:/data
    restart: unless-stopped
    
  redis-node-5:
    image: docker.io/redis:5.0.5
    container_name: redis-node-5
    command: redis-server 
      --cluster-enabled yes 
      --cluster-config-file nodes.conf 
      --cluster-node-timeout 5000 
      --cluster-migration-barrier 1
      --cluster-require-full-coverage no
      --appendonly yes 
      --port 17005
      --requirepass moxigame
      --masterauth moxigame
    network_mode: host
    volumes:
      - ./data/node-5:/data
    restart: unless-stopped
    
  redis-node-6:
    image: docker.io/redis:5.0.5
    container_name: redis-node-6
    command: redis-server 
      --cluster-enabled yes 
      --cluster-config-file nodes.conf 
      --cluster-node-timeout 5000 
      --cluster-migration-barrier 1
      --cluster-require-full-coverage no
      --appendonly yes 
      --port 17006
      --requirepass moxigame
      --masterauth moxigame
    network_mode: host
    volumes:
      - ./data/node-6:/data
    restart: unless-stopped

运行

docker compose up -d

创建集群

redis-cli -a moxigame --cluster create 10.0.1.247:17001 10.0.1.247:17002 10.0.1.247:17003 10.0.1.247:17004 10.0.1.247:17005 10.0.1.247:17006 --cluster-replicas 1 --cluster-yes

缩容

缩容从节点

# 移除从节点(格式:redis-cli --cluster del-node 集群节点地址 要下线的节点ID)
redis-cli -a moxigame --cluster del-node 10.0.1.247:17001 c9f280b217c2fdb9713732f527781ebef9d9f909

# 查看集群节点列表,确认 17004 已不存在
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17004

# 查看集群状态,确保正常
redis-cli -a moxigame -c -p 17001 cluster info | grep cluster_state
# 输出 cluster_state:ok

缩容主节点

# 连接集群,查看 17003 主节点信息
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17003
# 输出示例:
# 04d6252fe6ca1f48b3a4cd7ca37baa1c817a8786 10.0.1.247:17003@27003 myself,master - 0 1769133219646 3 connected 10923-16383
# 记录:主节点 ID=04d6252fe6ca1f48b3a4cd7ca37baa1c817a8786,哈希槽=10923-16383

# 进入任意主节点容器(如 17001)
docker exec -it redis-node-1 bash

# 执行槽位迁移(以迁移 17003 的 5461 个槽到 17001 为例)
redis-cli -a moxigame --cluster reshard 10.0.1.247:17001

交互步骤(按提示输入): How many slots do you want to move (from 1 to 16384)? → 输入 5461(17003 持有的槽数,10923-16383 共 5461 个); What is the receiving node ID? → 输入目标主节点 ID(如 17001 的 ID:234a5b1659e4142eee6d1e76a2f82a754eb909f9); Source node #1: → 输入源主节点 ID(17003 的 ID:04d6252fe6ca1f48b3a4cd7ca37baa1c817a8786); Source node #2: → 输入 done(表示仅从 17003 迁移); Do you want to proceed with the proposed reshard plan (yes/no)? → 输入 yes。

迁移完成验证:

# 查看 17003 的槽位,确认已无槽位
redis-cli -a moxigame -c -p 17001 cluster nodes | grep 17003
# 输出中无 "connected 10923-16383" 表示槽位迁移完成

验证

# 1. 查看集群节点,确认 17003/17006 已移除
redis-cli -a moxigame -c -p 17001 cluster nodes | grep -E "17003|17006"
# 无输出表示移除成功

# 2. 验证哈希槽全部分配
redis-cli -a moxigame -c -p 17001 cluster info | grep cluster_slots_assigned
# 输出 cluster_slots_assigned:16384 表示槽位无丢失

# 3. 测试数据读写(访问原 17003 的槽位)
redis-cli -a moxigame -c -p 17001 set test_reshard "success"
redis-cli -a moxigame -c -p 17001 get test_reshard
# 输出 "success" 表示读写正常

扩容

redis-cli -a moxigame --cluster add-node 10.0.1.247:17004 10.0.1.247:17001

备份

cp data

恢复