Redis集群

发布于:2025-06-12 ⋅ 阅读:(21) ⋅ 点赞:(0)

目录

Redis集群方式

主从模式

哨兵模式

集群模式

Redis 集群模式简介

核心特性

优势与局限

适用场景

与其他模式的对比

部署建议

Redis 多从节点(Slave)选举机制详解

选举触发条件

选举过程(基于 Raft 算法的变种)

关键规则与注意事项

示例场景

常见问题与优化

与其他模式的对比

实例一:三主三从,二扩展,成四主四从

添加节点

删除节点


Redis集群方式

主从模式

  • 基本概念:主从模式是一种数据备份和读写分离的模式。在这种模式下,有一个主节点(Master)和一个或多个从节点(Slave)。主节点负责处理所有的写操作,而从节点则复制主节点的数据,实现数据的冗余和备份。读操作可以在主节点和从节点上进行,从而实现读写分离,提高系统性能。

  • 工作原理:主节点将写操作记录在内存中的缓冲区,从节点从主节点获取这些写操作记录,并在自己的数据库上执行这些操作,从而保持与主节点的数据一致。

  • 优点

    • 实现数据冗余,提高数据可靠性。
    • 读写分离,提高系统性能。
  • 缺点

    • 主节点故障时,需要手动切换到从节点,故障恢复时间较长。
    • 主节点承担所有写操作,可能成为性能瓶颈。
    • 无法实现数据分片,受单节点内存限制。

哨兵模式

  • 基本概念:哨兵模式是在主从模式的基础上增加了故障转移的功能。哨兵模式下,除了主节点和从节点,还有一个或多个哨兵节点(Sentinel)。哨兵节点的主要任务是监控主节点和从节点的运行状态,并在主节点发生故障时,自动将从节点提升为主节点。

  • 工作原理:哨兵节点会定期检查主节点和从节点的运行状态。如果发现主节点发生故障,哨兵节点会在从节点中选举出一个新的主节点,并通知其他的从节点和哨兵节点。此外,哨兵节点还可以接收客户端的查询请求,返回当前的主节点信息,从而实现客户端的透明切换。

  • 优点

    • 自动故障转移,提高系统的高可用性。
    • 具有主从复制模式的所有优点,如数据冗余和读写分离。
  • 缺点

    • 配置和管理相对复杂。
    • 依然无法实现数据分片,受单节点内存限制。

集群模式

  • 基本概念:集群模式是一种分布式的解决方案,它允许多个Redis节点(服务器)协同工作,提供更高的性能和可用性。在这种模式下,数据被分片存储在多个节点上,每个节点负责一部分数据的读写。

  • 工作原理:Redis集群使用一种叫做哈希槽的技术来实现数据的分片。集群将数据分为16384个槽位,每个节点负责管理一部分槽位。当一个键需要被存储时,Redis会根据键的值计算出一个哈希值,然后根据哈希值决定将这个键存储在哪个节点上。这样,读写请求就可以在多个节点上并行处理,提高了系统的性能。

  • 优点

    • 实现数据的水平扩展,提高了系统的性能和存储容量。
    • 实现高可用性,即使某个节点发生故障,系统仍然可以继续提供服务。
  • 缺点

    • 配置和维护相对复杂,需要管理多个节点。
    • 某些操作,如多键操作和事务,可能会受到限制。

Redis 集群模式简介

Redis 集群模式(Redis Cluster)是一种分布式、去中心化的高可用解决方案,旨在解决单机和主从模式下的内存限制单点故障问题。通过数据分片和自动故障转移,集群模式可实现水平扩展高可用性,适用于大规模数据存储和高并发场景。

核心特性

  • 数据分片(Sharding)
    • 数据被分配到 16384 个哈希槽(Hash Slot) 中,每个节点负责一部分槽位。
    • 键的哈希值决定其存储位置(例如:CRC16(key) % 16384)。
    • 示例:若节点 A 负责槽位 0-5460,则键 "user:1000" 可能存储在节点 A。
  • 自动故障转移(Failover)
    • 节点间通过 Gossip 协议 通信,监控彼此状态。
    • 若主节点故障,其从节点会自动选举为新主节点(基于 Raft 算法 的变种)。
    • 客户端通过重定向(MOVED 或 ASK 指令)自动切换到新主节点。
  • 高可用性
    • 每个主节点可配置一个或多个从节点,实现 N+1 冗余
    • 集群要求至少 3 个主节点(推荐 3 主 3 从),以避免脑裂(Split-Brain)问题。
  • 水平扩展
    • 新增节点时,通过 重新分片(Resharding) 动态调整槽位分配。
    • 无需停机,支持在线扩容。

优势与局限

优势 局限
- 线性扩展存储和计算能力 - 跨节点事务和多键操作受限
- 自动故障转移,无需哨兵 - 键分布不均可能导致负载倾斜
- 数据分片减少单节点内存压力 - 配置复杂,需处理网络分区风险
- 客户端透明重定向(支持智能客户端) - 不支持 LRANGE 等大范围查询优化

适用场景
  • 大规模数据存储:单节点内存不足时(如 TB 级数据)。
  • 高并发读写:通过分片分散请求压力。
  • 需要自动故障转移:避免人工干预,提升运维效率。

不适用场景

  • 需要强一致性(集群最终一致性)。
  • 依赖多键操作(如 MGET 跨节点键)。
  • 复杂事务(跨节点事务需客户端处理)。

与其他模式的对比

模式 扩展性 高可用性 数据一致性 适用场景
主从模式 手动切换 强一致性 小规模数据、读多写少
哨兵模式 自动切换 强一致性 高可用性要求高的场景
集群模式 自动切换 最终一致性 大规模数据、高并发、分布式

部署建议

  • 节点数量:奇数个主节点(如 3、5、7),避免脑裂。
  • 网络要求:低延迟、高带宽,避免跨机房部署(除非使用 Proxy)。
  • 客户端支持:使用支持集群的客户端(如 Jedis Cluster、Lettuce)。

Redis 多从节点(Slave)选举机制详解

在 Redis 的主从复制和哨兵模式中,当主节点(Master)发生故障时,需要从多个从节点中选举出一个新的主节点。这一过程由 哨兵(Sentinel) 监控并主导,以下是其核心机制和关键点:


选举触发条件

  • 主节点故障:哨兵通过定期心跳检测(每秒一次)发现主节点不可达(如无响应或超时)。
  • 主观下线(Subjectively Down):单个哨兵认为主节点故障。
  • 客观下线(Objectively Down):多数哨兵(quorum 配置)达成共识,确认主节点故障。

选举过程(基于 Raft 算法的变种)

  1. 筛选候选从节点
    • 优先级(Slave Priority):优先选择配置了较高优先级的从节点(通过 replica-priority 参数设置,默认 100)。
    • 数据完整性:选择复制偏移量(offset)最大的从节点(即数据最接近主节点)。
    • 运行 ID 排序:若偏移量相同,选择运行 ID 较小的从节点(Redis 启动时生成,唯一且固定)。
  2. 执行故障转移
    • 哨兵向选定的从节点发送 SLAVEOF NO ONE 命令,将其提升为主节点。
    • 新主节点开始处理写请求,其他从节点自动复制新主节点的数据。
    • 哨兵更新集群配置,通知客户端主节点变更(通过发布/订阅或客户端重定向)。

关键规则与注意事项

  • 多数哨兵共识:选举需满足 quorum(如 3 个哨兵中至少 2 个同意),避免脑裂(Split-Brain)。
  • 避免循环选举:哨兵通过 leader epoch 标记选举轮次,防止重复投票。
  • 客户端影响
    • 客户端需支持哨兵模式(如 Jedis SentinelPool),自动重连新主节点。
    • 短暂不可用(故障转移期间通常 <10 秒),但依赖客户端重试机制。

示例场景

假设集群配置如下:

  • 主节点:M
  • 从节点:S1(优先级 100,偏移量 1000)、S2(优先级 50,偏移量 950)、S3(优先级 100,偏移量 1000)

选举结果

  1. 哨兵优先选择优先级高的从节点,排除 S2
  2. S1 和 S3 偏移量相同,选择运行 ID 较小的节点(假设为 S1)。
  3. S1 被提升为主节点,S3 和其他从节点开始复制 S1

常见问题与优化

  • 问题 1:多个哨兵同时发起选举,如何避免冲突?
    解答:哨兵通过 leader epoch 标记选举轮次,只有最新轮次的选举结果有效。

  • 问题 2:如何减少选举时间?
    解答

    • 降低 down-after-milliseconds(默认 30 秒)和 failover-timeout(默认 180 秒)以加速检测。
    • 增加哨兵节点数量(奇数个,如 3、5),提高共识速度。
  • 问题 3:如何避免数据丢失?
    解答

    • 配置 min-slaves-to-write 和 min-slaves-max-lag,确保至少一个从节点同步数据。
    • 使用半同步复制(需 Redis 6.0+ 或第三方模块)。

与其他模式的对比

模式 选举机制 适用场景
哨兵模式 哨兵主导,基于优先级和偏移量 高可用性要求高的生产环境
Redis 集群 无传统选举,主节点故障时从节点直接升级 大规模数据分片,自动故障转移

实例一:三主三从,二扩展,成四主四从

八台redis同时配置

[root@localhost ~]# dnf -y install gcc

 关闭防火墙及系统内核

[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0

压缩redis并编译

[root@localhost redis-5.0.14]# tar zxf redis
[root@localhost redis-5.0.14]# cd
[root@localhost redis-5.0.14]# make

编译安装

[root@localhost redis-5.0.14]# make PREFIX=/usr/local/redis install

环境变量

[root@localhost redis-5.0.14]# ln -s /usr/local/redis/bin/* /usr/local/bin/

 初始化数据库

[root@localhost redis-5.0.14]# cd utils/
[root@localhost utils]# ./install_server.sh 

 修改配置文件

[root@localhost utils]# vim /etc/redis/6379.conf
70行
bind 0.0.0.0
700行
appendonly yes
833行
去#号
cluster-enabled yes
841
去#号
cluster-config-file nodes-6379.conf
847
去#号
cluster-node-timeout 15000
924
yes改no	去#号
cluster-require-full-coverage no

重启redis

[root@localhost utils]# /etc/init.d/redis_6379 restart

 查看运行状态,八台redis都查看 看是否成功启动

[root@localhost utils]# netstat -anpt |grep redis

在01上创建集群,任何一台都行

[root@localhost utils]# redis-cli --cluster create --cluster-replicas 1 192.168.10.101:6379 192.168.10.102:6379 192.168.10.103:6379 192.168.10.104:6379 192.168.10.105:6379 192.168.10.106:6379

验证:

登录任意一台redis查看状态

[root@localhost utils]# redis-cli -h 192.168.10.105 -p 6379 -c
192.168.10.105:6379> set name zhangsan		#创建文件

查看状态

127.0.0.1:6379> cluster nodes
3813d0cdbb777d201199a5d69fffedd1b52b4430 192.168.10.101:6379@16379 master - 0 1745297107635 1 connected 0-5460
9041d75d159fa0bcfc862a947961674b9b1c5e36 192.168.10.104:6379@16379 slave 924230a965fc05ba46b8dc58cd9e1db06499429d 0 1745297109728 4 connected
1267c2de5be4c51bc0e95fe3e0fcd8264892e97e 192.168.10.105:6379@16379 slave 3813d0cdbb777d201199a5d69fffedd1b52b4430 0 1745297110782 5 connected
924230a965fc05ba46b8dc58cd9e1db06499429d 192.168.10.103:6379@16379 myself,master - 0 1745296992000 3 connected 10923-16383
f8e99e5dbb898c80cfffb9e68f42eb8422c4fa5f 192.168.10.102:6379@16379 master - 0 1745297108683 2 connected 5461-10922
1a16701a56d9238502b68b9e3aa4ec8838858cb8 192.168.10.106:6379@16379 slave f8e99e5dbb898c80cfffb9e68f42eb8422c4fa5f 0 1745297111842 6 connected
  • 3813d0cdbb777d201199a5d69fffedd1b52b4430:hash算法后的id
  • 192.168.10.101:6379@16379:ip以及连接端口
  • master - 0:角色是否为master或者slave -是连接的master的id
  • slave 3813d0cdbb777d201199a5d69fffedd1b52b4430:slave:角色 381*****:是id
  • myself,master:myself指:本机 master是角色

添加节点

扩展方法一:

[root@localhost utils]# redis-cli -c -p 6379 cluster meet 192.168.10.107 6379	#指定添加的ip 端口
在其他节点查看,会发现没有分配槽
192.168.10.105:6379> cluster nodes

扩展方法二:

[root@localhost utils]# redis-cli --clusteer add-node 192.168.10.108:6379 192.168.10.107:6379
登录进去查看状态
192.168.10.105:6379> cluster nodes

108是新要添加的节点,而107是节点中集群中任意一个节点

查看会发现会发现两台都是master

删除节点

[root@localhost utils]# redis-cli
127.0.0.1:6379> flushall    清空
127.0.0.1:6379> cluster reset    重载

[root@localhost utils]# redis-cli --cluster del-node 192.168.10.108:6379 id#108的id

 修改新节点为其他节点的从节点

[root@localhost utils]# redis-cli 192.168.10.108 -p 6379
登录进去
cldis-cli replicate 107的id

重新分配槽位

redis-cli --cluster rebalance --cluster-threshold 1 --cluster-use-empty-masters 192.168.10.101:6379

如果故障了出现问题,先清空数据以及重载集群在执行所出问题的命令

登录进去
127.0.0.1:6379> flushall
127.0.0.1:6379> cluster reset

 

 

 

 

 

 

 

 

 

 

 

 


网站公告

今日签到

点亮在社区的每一天
去签到