当前位置: 代码网 > it编程>数据库>Redis > redis分布式设计的实现示例

redis分布式设计的实现示例

2026年05月08日 Redis 我要评论
redis 的分布式设计主要通过三种模式实现,每种模式解决不同的问题:一、三种分布式模式对比模式解决的问题数据关系适用场景主从复制读写分离、数据备份全量复制读多写少、数据备份哨兵模式高可用、自动故障转

redis 的分布式设计主要通过三种模式实现,每种模式解决不同的问题:

一、三种分布式模式对比

模式解决的问题数据关系适用场景
主从复制读写分离、数据备份全量复制读多写少、数据备份
哨兵模式高可用、自动故障转移全量复制需要自动容灾
cluster 集群水平扩展、海量数据分片存储数据量大、需要扩展

二、主从复制(replication)

核心机制

┌─────────┐         全量/增量复制          ┌─────────┐
│  master │  ───────────────────────────►  │  slave  │
│  (写)   │                              │  (读)   │
└─────────┘                              └─────────┘

复制流程

1. slave 发送 sync/psync 命令
2. master 执行 bgsave,生成 rdb 文件
3. master 将 rdb 发送给 slave
4. slave 加载 rdb
5. 后续写命令实时同步(增量复制)

关键配置

# slave 配置
replicaof 192.168.1.10 6379
masterauth <password>
# 只读(默认)
replica-read-only yes

问题

  • 无法自动故障转移:master 挂了需要手动切换
  • 写压力集中在 master
  • 复制延迟:slave 数据可能落后

三、哨兵模式(sentinel)

在主从基础上增加自动监控和故障转移。

架构

        ┌─────────┐
        │ client  │
        └────┬────┘
             │
    ┌────────┼────────┐
    ▼        ▼        ▼
┌───────┐ ┌───────┐ ┌───────┐
│sentinel│ │sentinel│ │sentinel│  (至少3个,投票决策)
│  1    │ │  2    │ │  3    │
└────┬───┘ └────┬───┘ └────┬───┘
     │          │          │
     └──────────┼──────────┘
                ▼
        ┌─────────────┐
        │   master    │
        └──────┬──────┘
               │
        ┌──────┴──────┐
        ▼             ▼
    ┌───────┐     ┌───────┐
    │ slave1│     │ slave2│
    └───────┘     └───────┘

哨兵的核心功能

功能说明
监控定期检查 master/slave 是否存活
通知故障时通知管理员或其他应用
自动故障转移master 宕机时,选举 slave 为新 master
配置提供者客户端向 sentinel 询问当前 master 地址

故障转移流程

1. 主观下线(sdown):某个 sentinel 发现 master 无响应
2. 客观下线(odown):多个 sentinel 投票确认 master 故障
3. 选举 leader sentinel:raft 算法投票
4. 选择最优 slave(优先级高、复制偏移量大、runid小)
5. 提升为 master,其他 slave 重新配置
6. 通知客户端更新 master 地址

客户端连接方式

# python 示例:sentinel 自动发现 master
from redis.sentinel import sentinel
sentinel = sentinel([
    ('sentinel1', 26379),
    ('sentinel2', 26379),
    ('sentinel3', 26379)
])
# 自动获取当前 master
master = sentinel.master_for('mymaster', password='xxx')
slave = sentinel.slave_for('mymaster', password='xxx')
master.set('key', 'value')
value = slave.get('key')

缺点

  • 只有一个 master 写,无法水平扩展写性能
  • 数据量受限于单节点内存

四、cluster 集群(最核心)

redis 真正的分布式方案,通过数据分片实现水平扩展。

架构

┌─────────────────────────────────────────────┐
│              redis cluster                   │
│                                              │
│   ┌─────────┐  ┌─────────┐  ┌─────────┐     │
│   │ node 1  │  │ node 2  │  │ node 3  │     │
│   │ [0-5460]│  │[5461-10922]│[10923-16383] │
│   │ master a│  │ master b│  │ master c│     │
│   └───┬─────┘  └────┬────┘  └────┬────┘     │
│       │             │            │          │
│   ┌───┴───┐    ┌───┴───┐   ┌───┴───┐      │
│   │slave a1│    │slave b1│   │slave c1│     │
│   └────────┘    └────────┘   └────────┘      │
│                                              │
│   16384 个哈希槽(slot)均匀分配到各 master    │
└─────────────────────────────────────────────┘

核心概念:哈希槽(hash slot)

slot = crc16(key) % 16384
key "user:1000" → crc16 = 12345 → 12345 % 16384 = 12345 → 属于 node 3

为什么用 16384 个槽?

  • crc16 输出范围 0~65535
  • 16384 = 2^14,平衡了元数据大小和分片粒度
  • 集群节点配置中传播的是槽位映射,不是具体 key

节点通信:gossip 协议

每个节点每秒随机向几个其他节点发送 ping
携带:自身状态 + 已知其他节点的状态

通过"谣言传播"方式,最终整个集群状态一致

客户端路由

┌─────────┐
│ client  │
└────┬────┘
     │  set key value
     ▼
┌─────────┐  计算 key 的 slot
│ node 1  │  发现 slot 不在本地
└────┬────┘
     │ 返回 moved 错误,告知正确节点
     ▼
┌─────────┐
│ client  │  重定向到正确节点
└────┬────┘
     ▼
┌─────────┐
│ node 3  │  执行命令
└─────────┘

smart client(如 redis-py-cluster)会缓存槽位映射,减少重定向。

数据迁移(扩容/缩容)

1. 新节点加入集群
2. 分配部分 slot 给新节点(如从 node1 迁 1000 个 slot)
3. 迁移过程中:
   - 源节点:迁出的 slot 标记为 importing
   - 目标节点:标记为 migrating
   - 迁移中的 key:先查源节点,没有则查目标节点
4. 迁移完成后更新槽位映射

cluster 配置示例

# redis.conf
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 5000
cluster-require-full-coverage no  # 部分槽不可用时不拒绝所有请求
# 创建集群(6 节点,3 主 3 从)
redis-cli --cluster create \
  192.168.1.11:6379 192.168.1.12:6379 192.168.1.13:6379 \
  192.168.1.14:6379 192.168.1.15:6379 192.168.1.16:6379 \
  --cluster-replicas 1

五、三种模式对比总结

维度主从复制哨兵模式cluster 集群
数据容量单机内存单机内存多机总和
写性能单机单机水平扩展
读性能扩展扩展扩展
高可用手动切换自动切换自动切换
数据分片
复杂度

六、生产环境建议

场景推荐方案
数据 < 10gb,读多写少主从 + 哨兵
数据 > 10gb 或需要扩展写cluster 集群
需要跨机房容灾cluster + 主从交叉部署
超大规模(tb 级)业务分片 + 多 cluster

七、常见问题

1. cluster 的 key 限制

# 默认不支持跨 slot 的多 key 操作
mget key1 key2  # 如果 key1 和 key2 在不同 slot,报错

# 解决方案:hash tag
mget {user:1000}:name {user:1000}:age  
# {} 内内容用于计算 slot,确保同一用户数据在同一节点

2. 脑裂问题

网络分区时,原 master 和 sentinel 隔离
sentinel 选举新 master → 出现两个 master
解决方案:min-slaves-to-write 配置,确保有足够 slave 才接受写

3. 数据倾斜

big key 或 hash tag 使用不当导致某些 slot 数据量过大
解决方案:监控 slot 大小,避免 big key,合理设计 key

到此这篇关于redis分布式设计的实现示例的文章就介绍到这了,更多相关redis分布式设计内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com