Redis Cluster集群架构与槽位迁移配置实战

Redis Cluster通过数据分片实现水平扩展,将16384个哈希槽分配到多个主节点,每个主节点配一个从节点提供高可用。与哨兵模式相比,Cluster方案通过数据分片突破单节点内存和性能上限,支持在线扩缩容。本文从集群拓扑设计、槽位分配、在线迁移、故障转移四个维度展开配置实战。

Redis Cluster集群拓扑与哈希槽分配

Redis Cluster采用无中心架构,每个节点通过Gossip协议交换集群状态。客户端连接任意节点,收到MOVED重定向后缓存槽位映射。16384个哈希槽的设计使扩缩容时迁移粒度可控,单个槽位迁移不影响其他槽位服务。

# 创建6节点集群(3主3从)
# redis.conf 配置
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.1.100
cluster-announce-port 7000
cluster-announce-bus-port 17000
appendonly yes
appendfsync everysec

# 启动6个实例(7000-7005)
for port in 7000 7001 7002 7003 7004 7005; do
    redis-server --port $port \
        --cluster-enabled yes \
        --cluster-config-file nodes-${port}.conf \
        --cluster-node-timeout 5000 \
        --appendonly yes &
done

# 创建集群,自动分配槽位
redis-cli --cluster create \
    192.168.1.100:7000 192.168.1.100:7001 192.168.1.100:7002 \
    192.168.1.100:7003 192.168.1.100:7004 192.168.1.100:7005 \
    --cluster-replicas 1

# 查看集群状态
redis-cli -p 7000 cluster nodes
redis-cli -p 7000 cluster info
# cluster_state:ok
# cluster_slots_assigned:16384
# cluster_slots_ok:16384
# cluster_known_nodes:6

哈希槽映射与数据定向写入

Redis Cluster使用CRC16算法计算键的哈希槽:slot = CRC16(key) mod 16384。哈希标签{tag}内的字符串参与哈希计算,将相关键分配到同一槽位实现事务和Lua脚本的跨键操作。

# 哈希标签实现多键操作
# user:1001:profile 和 user:1001:orders 落在同一槽位
SET {user:1001}:profile "Alice"
SET {user:1001}:orders "order_list"
SET {user:1001}:cart "items"

# 同槽位键支持MULTI/EXEC事务
MULTI
GET {user:1001}:profile
GET {user:1001}:cart
EXEC

# 验证槽位分配
redis-cli -p 7000 cluster keyslot {user:1001}
# 返回: (integer) 12345

# 查看指定槽位所在节点
redis-cli -p 7000 cluster slots
# 1) 1) (integer) 0          -- 起始槽位
#    2) (integer) 5460        -- 结束槽位
#    3) 1) "192.168.1.100"    -- 主节点IP
#       2) (integer) 7000
#       3) "abc123..."        -- 节点ID
#    4) 1) "192.168.1.100"    -- 从节点IP
#       2) (integer) 7003

# 客户端连接(Smart Client自动缓存路由表)
import redis

r = redis.RedisCluster(
    startup_nodes=[
        redis.ClusterNode('192.168.1.100', 7000),
        redis.ClusterNode('192.168.1.100', 7001),
    ],
    decode_responses=True,
    cluster_error_retry_attempts=3,
    read_from_replicas=True,
)

r.set('{user:1001}:name', 'Alice')
r.set('{user:1001}:age', '30')

# Pipeline批量操作(自动分扇出到各节点)
with r.pipeline() as pipe:
    for i in range(1000):
        pipe.set(f'key:{i}', f'value:{i}')
    pipe.execute()

在线槽位迁移与集群扩容

Redis Cluster支持在线迁移槽位,迁移过程中不影响集群服务。MIGRATE命令将源节点数据原子转移到目标节点,迁移完成后更新集群路由表。

# 新增节点扩容
# 启动新主节点7006和新从节点7007
redis-server --port 7006 --cluster-enabled yes \
    --cluster-config-file nodes-7006.conf --appendonly yes &
redis-server --port 7007 --cluster-enabled yes \
    --cluster-config-file nodes-7007.conf --appendonly yes &

# 将新节点加入集群
redis-cli --cluster add-node 192.168.1.100:7006 192.168.1.100:7000
# 设置7007为7006的从节点
redis-cli --cluster add-node 192.168.1.100:7007 192.168.1.100:7000 \
    --cluster-slave --cluster-master-id <7006node_id>

# 自动化分配(脚本方式)
redis-cli --cluster reshard 192.168.1.100:7000 \
    --cluster-from ,, \
    --cluster-to  \
    --cluster-slots 4096 \
    --cluster-yes

# 查看迁移进度
redis-cli -p 7000 cluster nodes | grep migrating
redis-cli -p 7006 cluster nodes | grep importing

# 槽位迁移底层执行(手动方式)
# 1. 通知源节点准备迁移
CLUSTER SETSLOT 8192 MIGRATING 
# 2. 通知目标节点准备导入
CLUSTER SETSLOT 8192 IMPORTING 
# 3. 迁移数据
MIGRATE 192.168.1.100 7006 "" 0 5000 KEYS key1 key2 key3
# 4. 通知全集群槽位归属变更
CLUSTER SETSLOT 8192 NODE 

故障检测与自动转移机制

当主节点故障,从节点通过Gossip协议检测到主节点下线后发起选举。获得多数主节点投票后升级为新主节点,接管故障主节点的槽位。

# 模拟主节点故障
redis-cli -p 7000 shutdown nosave

# 观察从节点7003选举升级
redis-cli -p 7001 cluster nodes
# 7000节点显示 disconnected/fail
# 7003节点从slave变为master

# 手动故障转移(计划内维护)
redis-cli -p 7003 cluster failover
# 命令序列:
# 1. 从节点通知主节点停止处理写入
# 2. 从节点同步主节点最新数据
# 3. 从节点广播升级消息
# 4. 主节点降级为从节点

# 强制故障转移(主节点不可达时)
redis-cli -p 7003 cluster failover FORCE

# 集群不一致修复
redis-cli --cluster fix 192.168.1.100:7000

# 查看集群健康状态
redis-cli --cluster check 192.168.1.100:7000
# [OK] All nodes agree about slots configuration.
# [OK] All 16384 slots covered.
# [OK] At least 1 replica for each master.

生产环境运维与监控指标

# Redis Exporter + Prometheus 监控
# 关键指标:
# redis_cluster_state                    集群状态(1=ok)
# redis_cluster_slots_assigned           已分配槽位数
# redis_cluster_slots_ok                 正常槽位数
# redis_cluster_known_nodes              已知节点数
# redis_cluster_links_peers              集群连接数
# redis_db_keys                          键数量
# redis_memory_used_bytes                内存使用量
# redis_connected_clients                客户端连接数

# 超时与重试配置
import redis

r = redis.RedisCluster(
    startup_nodes=[redis.ClusterNode('192.168.1.100', 7000)],
    max_connections=100,
    socket_timeout=2.0,
    socket_connect_timeout=2.0,
    retry_on_timeout=True,
    cluster_error_retry_attempts=5,
    read_from_replicas=True,
    route_read_from_replicas_strategy="ALL_NODES",
)

# 批量SCAN集群所有键
def scan_cluster_keys(cluster, pattern='*'):
    all_keys = []
    for node in cluster.get_nodes():
        if node['flags'] & redis.CLUSTER_NODE_MASTER:
            client = redis.Redis(
                host=node['host'], port=node['port'],
                decode_responses=True
            )
            cursor = 0
            while True:
                cursor, keys = client.scan(
                    cursor=cursor, match=pattern, count=1000
                )
                all_keys.extend(keys)
                if cursor == 0:
                    break
    return all_keys

cluster-node-timeout设置过大导致故障检测延迟,过小导致网络抖动误判主节点下线。生产环境建议5-10秒,配合cluster-announce-ip确保跨网段Gossip通信正常。迁移槽位时控制单批迁移数量,避免大量MIGRATE阻塞源节点事件循环。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rediscluster-ji-qun-jia-gou-yu-cao-wei-qian-yi-pei-zhi-shi/

(0)
小编小编
上一篇 5小时前
下一篇 5小时前

相关推荐

Redis Cluster集群架构与槽位迁移配置实战

Redis Cluster通过数据分片实现水平扩展,将16384个哈希槽分配到多个主节点,每个主节点配一个从节点提供高可用。与哨兵模式相比,Cluster方案通过数据分片突破单节点内存和性能上限,支持在线扩缩容。本文从集群拓扑设计、槽位分配、在线迁移、故障转移四个维度展开配置实战。

Redis Cluster集群拓扑与哈希槽分配

Redis Cluster采用无中心架构,每个节点通过Gossip协议交换集群状态。客户端连接任意节点,收到MOVED重定向后缓存槽位映射。16384个哈希槽的设计使扩缩容时迁移粒度可控,单个槽位迁移不影响其他槽位服务。

# 创建6节点集群(3主3从)
# redis.conf 配置
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.1.100
cluster-announce-port 7000
cluster-announce-bus-port 17000
appendonly yes
appendfsync everysec

# 启动6个实例(7000-7005)
for port in 7000 7001 7002 7003 7004 7005; do
    redis-server --port $port \
        --cluster-enabled yes \
        --cluster-config-file nodes-${port}.conf \
        --cluster-node-timeout 5000 \
        --appendonly yes &
done

# 创建集群,自动分配槽位
redis-cli --cluster create \
    192.168.1.100:7000 192.168.1.100:7001 192.168.1.100:7002 \
    192.168.1.100:7003 192.168.1.100:7004 192.168.1.100:7005 \
    --cluster-replicas 1

# 查看集群状态
redis-cli -p 7000 cluster nodes
redis-cli -p 7000 cluster info
# cluster_state:ok
# cluster_slots_assigned:16384
# cluster_slots_ok:16384
# cluster_known_nodes:6

哈希槽映射与数据定向写入

Redis Cluster使用CRC16算法计算键的哈希槽:slot = CRC16(key) mod 16384。哈希标签{tag}内的字符串参与哈希计算,将相关键分配到同一槽位实现事务和Lua脚本的跨键操作。

# 哈希标签实现多键操作
# user:1001:profile 和 user:1001:orders 落在同一槽位
SET {user:1001}:profile "Alice"
SET {user:1001}:orders "order_list"
SET {user:1001}:cart "items"

# 同槽位键支持MULTI/EXEC事务
MULTI
GET {user:1001}:profile
GET {user:1001}:cart
EXEC

# 验证槽位分配
redis-cli -p 7000 cluster keyslot {user:1001}
# 返回: (integer) 12345

# 查看指定槽位所在节点
redis-cli -p 7000 cluster slots
# 1) 1) (integer) 0          -- 起始槽位
#    2) (integer) 5460        -- 结束槽位
#    3) 1) "192.168.1.100"    -- 主节点IP
#       2) (integer) 7000
#       3) "abc123..."        -- 节点ID
#    4) 1) "192.168.1.100"    -- 从节点IP
#       2) (integer) 7003

# 客户端连接(Smart Client自动缓存路由表)
import redis

r = redis.RedisCluster(
    startup_nodes=[
        redis.ClusterNode('192.168.1.100', 7000),
        redis.ClusterNode('192.168.1.100', 7001),
    ],
    decode_responses=True,
    cluster_error_retry_attempts=3,
    read_from_replicas=True,
)

r.set('{user:1001}:name', 'Alice')
r.set('{user:1001}:age', '30')

# Pipeline批量操作(自动分扇出到各节点)
with r.pipeline() as pipe:
    for i in range(1000):
        pipe.set(f'key:{i}', f'value:{i}')
    pipe.execute()

在线槽位迁移与集群扩容

Redis Cluster支持在线迁移槽位,迁移过程中不影响集群服务。MIGRATE命令将源节点数据原子转移到目标节点,迁移完成后更新集群路由表。

# 新增节点扩容
# 启动新主节点7006和新从节点7007
redis-server --port 7006 --cluster-enabled yes \
    --cluster-config-file nodes-7006.conf --appendonly yes &
redis-server --port 7007 --cluster-enabled yes \
    --cluster-config-file nodes-7007.conf --appendonly yes &

# 将新节点加入集群
redis-cli --cluster add-node 192.168.1.100:7006 192.168.1.100:7000
# 设置7007为7006的从节点
redis-cli --cluster add-node 192.168.1.100:7007 192.168.1.100:7000 \
    --cluster-slave --cluster-master-id <7006node_id>

# 自动化分配(脚本方式)
redis-cli --cluster reshard 192.168.1.100:7000 \
    --cluster-from ,, \
    --cluster-to  \
    --cluster-slots 4096 \
    --cluster-yes

# 查看迁移进度
redis-cli -p 7000 cluster nodes | grep migrating
redis-cli -p 7006 cluster nodes | grep importing

# 槽位迁移底层执行(手动方式)
# 1. 通知源节点准备迁移
CLUSTER SETSLOT 8192 MIGRATING 
# 2. 通知目标节点准备导入
CLUSTER SETSLOT 8192 IMPORTING 
# 3. 迁移数据
MIGRATE 192.168.1.100 7006 "" 0 5000 KEYS key1 key2 key3
# 4. 通知全集群槽位归属变更
CLUSTER SETSLOT 8192 NODE 

故障检测与自动转移机制

当主节点故障,从节点通过Gossip协议检测到主节点下线后发起选举。获得多数主节点投票后升级为新主节点,接管故障主节点的槽位。

# 模拟主节点故障
redis-cli -p 7000 shutdown nosave

# 观察从节点7003选举升级
redis-cli -p 7001 cluster nodes
# 7000节点显示 disconnected/fail
# 7003节点从slave变为master

# 手动故障转移(计划内维护)
redis-cli -p 7003 cluster failover
# 命令序列:
# 1. 从节点通知主节点停止处理写入
# 2. 从节点同步主节点最新数据
# 3. 从节点广播升级消息
# 4. 主节点降级为从节点

# 强制故障转移(主节点不可达时)
redis-cli -p 7003 cluster failover FORCE

# 集群不一致修复
redis-cli --cluster fix 192.168.1.100:7000

# 查看集群健康状态
redis-cli --cluster check 192.168.1.100:7000
# [OK] All nodes agree about slots configuration.
# [OK] All 16384 slots covered.
# [OK] At least 1 replica for each master.

生产环境运维与监控指标

# Redis Exporter + Prometheus 监控
# 关键指标:
# redis_cluster_state                    集群状态(1=ok)
# redis_cluster_slots_assigned           已分配槽位数
# redis_cluster_slots_ok                 正常槽位数
# redis_cluster_known_nodes              已知节点数
# redis_cluster_links_peers              集群连接数
# redis_db_keys                          键数量
# redis_memory_used_bytes                内存使用量
# redis_connected_clients                客户端连接数

# 超时与重试配置
import redis

r = redis.RedisCluster(
    startup_nodes=[redis.ClusterNode('192.168.1.100', 7000)],
    max_connections=100,
    socket_timeout=2.0,
    socket_connect_timeout=2.0,
    retry_on_timeout=True,
    cluster_error_retry_attempts=5,
    read_from_replicas=True,
    route_read_from_replicas_strategy="ALL_NODES",
)

# 批量SCAN集群所有键
def scan_cluster_keys(cluster, pattern='*'):
    all_keys = []
    for node in cluster.get_nodes():
        if node['flags'] & redis.CLUSTER_NODE_MASTER:
            client = redis.Redis(
                host=node['host'], port=node['port'],
                decode_responses=True
            )
            cursor = 0
            while True:
                cursor, keys = client.scan(
                    cursor=cursor, match=pattern, count=1000
                )
                all_keys.extend(keys)
                if cursor == 0:
                    break
    return all_keys

cluster-node-timeout设置过大导致故障检测延迟,过小导致网络抖动误判主节点下线。生产环境建议5-10秒,配合cluster-announce-ip确保跨网段Gossip通信正常。迁移槽位时控制单批迁移数量,避免大量MIGRATE阻塞源节点事件循环。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rediscluster-ji-qun-jia-gou-yu-cao-wei-qian-yi-pei-zhi-shi/

(0)
小编小编
上一篇 6小时前
下一篇 6小时前

相关推荐

Redis Cluster集群架构与槽位迁移配置实战

Redis Cluster通过数据分片实现水平扩展,将16384个哈希槽分配到多个主节点,每个主节点配一个从节点提供高可用。与哨兵模式相比,Cluster方案通过数据分片突破单节点内存和性能上限,支持在线扩缩容。本文从集群拓扑设计、槽位分配、在线迁移、故障转移四个维度展开配置实战。

Redis Cluster集群拓扑与哈希槽分配

Redis Cluster采用无中心架构,每个节点通过Gossip协议交换集群状态。客户端连接任意节点,收到MOVED重定向后缓存槽位映射。16384个哈希槽的设计使扩缩容时迁移粒度可控,单个槽位迁移不影响其他槽位服务。

# 创建6节点集群(3主3从)
# redis.conf 配置
port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.1.100
cluster-announce-port 7000
cluster-announce-bus-port 17000
appendonly yes
appendfsync everysec

# 启动6个实例(7000-7005)
for port in 7000 7001 7002 7003 7004 7005; do
    redis-server --port $port \
        --cluster-enabled yes \
        --cluster-config-file nodes-${port}.conf \
        --cluster-node-timeout 5000 \
        --appendonly yes &
done

# 创建集群,自动分配槽位
redis-cli --cluster create \
    192.168.1.100:7000 192.168.1.100:7001 192.168.1.100:7002 \
    192.168.1.100:7003 192.168.1.100:7004 192.168.1.100:7005 \
    --cluster-replicas 1

# 查看集群状态
redis-cli -p 7000 cluster nodes
redis-cli -p 7000 cluster info
# cluster_state:ok
# cluster_slots_assigned:16384
# cluster_slots_ok:16384
# cluster_known_nodes:6

哈希槽映射与数据定向写入

Redis Cluster使用CRC16算法计算键的哈希槽:slot = CRC16(key) mod 16384。哈希标签{tag}内的字符串参与哈希计算,将相关键分配到同一槽位实现事务和Lua脚本的跨键操作。

# 哈希标签实现多键操作
# user:1001:profile 和 user:1001:orders 落在同一槽位
SET {user:1001}:profile "Alice"
SET {user:1001}:orders "order_list"
SET {user:1001}:cart "items"

# 同槽位键支持MULTI/EXEC事务
MULTI
GET {user:1001}:profile
GET {user:1001}:cart
EXEC

# 验证槽位分配
redis-cli -p 7000 cluster keyslot {user:1001}
# 返回: (integer) 12345

# 查看指定槽位所在节点
redis-cli -p 7000 cluster slots
# 1) 1) (integer) 0          -- 起始槽位
#    2) (integer) 5460        -- 结束槽位
#    3) 1) "192.168.1.100"    -- 主节点IP
#       2) (integer) 7000
#       3) "abc123..."        -- 节点ID
#    4) 1) "192.168.1.100"    -- 从节点IP
#       2) (integer) 7003

# 客户端连接(Smart Client自动缓存路由表)
import redis

r = redis.RedisCluster(
    startup_nodes=[
        redis.ClusterNode('192.168.1.100', 7000),
        redis.ClusterNode('192.168.1.100', 7001),
    ],
    decode_responses=True,
    cluster_error_retry_attempts=3,
    read_from_replicas=True,
)

r.set('{user:1001}:name', 'Alice')
r.set('{user:1001}:age', '30')

# Pipeline批量操作(自动分扇出到各节点)
with r.pipeline() as pipe:
    for i in range(1000):
        pipe.set(f'key:{i}', f'value:{i}')
    pipe.execute()

在线槽位迁移与集群扩容

Redis Cluster支持在线迁移槽位,迁移过程中不影响集群服务。MIGRATE命令将源节点数据原子转移到目标节点,迁移完成后更新集群路由表。

# 新增节点扩容
# 启动新主节点7006和新从节点7007
redis-server --port 7006 --cluster-enabled yes \
    --cluster-config-file nodes-7006.conf --appendonly yes &
redis-server --port 7007 --cluster-enabled yes \
    --cluster-config-file nodes-7007.conf --appendonly yes &

# 将新节点加入集群
redis-cli --cluster add-node 192.168.1.100:7006 192.168.1.100:7000
# 设置7007为7006的从节点
redis-cli --cluster add-node 192.168.1.100:7007 192.168.1.100:7000 \
    --cluster-slave --cluster-master-id <7006node_id>

# 自动化分配(脚本方式)
redis-cli --cluster reshard 192.168.1.100:7000 \
    --cluster-from ,, \
    --cluster-to  \
    --cluster-slots 4096 \
    --cluster-yes

# 查看迁移进度
redis-cli -p 7000 cluster nodes | grep migrating
redis-cli -p 7006 cluster nodes | grep importing

# 槽位迁移底层执行(手动方式)
# 1. 通知源节点准备迁移
CLUSTER SETSLOT 8192 MIGRATING 
# 2. 通知目标节点准备导入
CLUSTER SETSLOT 8192 IMPORTING 
# 3. 迁移数据
MIGRATE 192.168.1.100 7006 "" 0 5000 KEYS key1 key2 key3
# 4. 通知全集群槽位归属变更
CLUSTER SETSLOT 8192 NODE 

故障检测与自动转移机制

当主节点故障,从节点通过Gossip协议检测到主节点下线后发起选举。获得多数主节点投票后升级为新主节点,接管故障主节点的槽位。

# 模拟主节点故障
redis-cli -p 7000 shutdown nosave

# 观察从节点7003选举升级
redis-cli -p 7001 cluster nodes
# 7000节点显示 disconnected/fail
# 7003节点从slave变为master

# 手动故障转移(计划内维护)
redis-cli -p 7003 cluster failover
# 命令序列:
# 1. 从节点通知主节点停止处理写入
# 2. 从节点同步主节点最新数据
# 3. 从节点广播升级消息
# 4. 主节点降级为从节点

# 强制故障转移(主节点不可达时)
redis-cli -p 7003 cluster failover FORCE

# 集群不一致修复
redis-cli --cluster fix 192.168.1.100:7000

# 查看集群健康状态
redis-cli --cluster check 192.168.1.100:7000
# [OK] All nodes agree about slots configuration.
# [OK] All 16384 slots covered.
# [OK] At least 1 replica for each master.

生产环境运维与监控指标

# Redis Exporter + Prometheus 监控
# 关键指标:
# redis_cluster_state                    集群状态(1=ok)
# redis_cluster_slots_assigned           已分配槽位数
# redis_cluster_slots_ok                 正常槽位数
# redis_cluster_known_nodes              已知节点数
# redis_cluster_links_peers              集群连接数
# redis_db_keys                          键数量
# redis_memory_used_bytes                内存使用量
# redis_connected_clients                客户端连接数

# 超时与重试配置
import redis

r = redis.RedisCluster(
    startup_nodes=[redis.ClusterNode('192.168.1.100', 7000)],
    max_connections=100,
    socket_timeout=2.0,
    socket_connect_timeout=2.0,
    retry_on_timeout=True,
    cluster_error_retry_attempts=5,
    read_from_replicas=True,
    route_read_from_replicas_strategy="ALL_NODES",
)

# 批量SCAN集群所有键
def scan_cluster_keys(cluster, pattern='*'):
    all_keys = []
    for node in cluster.get_nodes():
        if node['flags'] & redis.CLUSTER_NODE_MASTER:
            client = redis.Redis(
                host=node['host'], port=node['port'],
                decode_responses=True
            )
            cursor = 0
            while True:
                cursor, keys = client.scan(
                    cursor=cursor, match=pattern, count=1000
                )
                all_keys.extend(keys)
                if cursor == 0:
                    break
    return all_keys

cluster-node-timeout设置过大导致故障检测延迟,过小导致网络抖动误判主节点下线。生产环境建议5-10秒,配合cluster-announce-ip确保跨网段Gossip通信正常。迁移槽位时控制单批迁移数量,避免大量MIGRATE阻塞源节点事件循环。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/rediscluster-ji-qun-jia-gou-yu-cao-wei-qian-yi-pei-zhi-shi/

(0)
小编小编
上一篇 6小时前
下一篇 6小时前

相关推荐