Redis的主从、哨兵及集群

1.整体架构

主机 IP 原有角色 新增 Redis 角色
MysqlMaster 172.25.254.135 MySQL 主库 Redis 主节点 + 1 个 Sentinel
MysqlSlave1 172.25.254.136 MySQL 从库 1 Redis 从节点 1 + 1 个 Sentinel
MysqlSlave2 172.25.254.137 MySQL 从库 2 Redis 从节点 2 + 1 个 Sentinel
MHA-Manager 172.25.254.x(管理机) MHA 管理机 第 4 台:额外部署 Sentinel;后续搭建 Redis Cluster 时作为集群节点

2.前置通用准备

2.1 关闭防火墙、SELinux(实验环境)

bash 复制代码
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

2.2 安装依赖

bash 复制代码
yum install -y gcc gcc-c++ make tcl wget

1. gcc / gcc-c++

  • gcc:C 语言编译器
  • gcc-c++:C++ 语言编译器
  • 用途:Redis 是 C 语言开发的源码包,下载.tar.gz源码后必须用 gcc 编译生成可执行程序redis-serverredis-cli,没有编译器无法编译安装 Redis。

2. make

  • 编译自动化工具,配合 gcc 使用
  • 用途:进入 Redis 源码目录执行makemake install,自动批量编译所有源码文件,简化编译流程。

3. tcl

  • Tcl 脚本语言运行库
  • Redis 编译完成后自带测试脚本,编译结束会自动执行测试校验程序,依赖 tcl 环境;缺少 tcl 会编译警告 / 失败。

4. wget

  • 网络下载工具
  • 用途:通过命令行直接下载 Redis 官方源码压缩包

2.3 下载、编译安装 Redis

bash 复制代码
cd /usr/local/src
wget https://download.redis.io/releases/redis-6.2.14.tar.gz
tar -zxvf redis-6.2.14.tar.gz
cd redis-6.2.14
make && make install

2.4 创建统一目录

bash 复制代码
mkdir -p /usr/local/redis/{conf,data,logs}
  • conf:存放配置文件
  • data:rdb/aof 持久化文件
  • logs:日志文件

3 搭建过程

3.1 Redis的一主二从

如果之前搭建过MySQL的一主二从,不用担心对Redis产生影响,因为MySQL 运行 mysqld 数据库进程,监听端口 3306;Redis 运行 redis-server 缓存进程,监听端口 6379(哨兵 26379); 两者是完全独立的软件程序,端口、进程、存储目录互不占用,不会互相抢占端口、内存、CPU。并且二者数据存放的目录、主从复制逻辑也不同。

3.1.1 实验概况及Redis主从复制原理

3.1.1.1 部署架构

Master(135):唯一写入节点,接收 SET/HSET/DEL 等写指令;

Replica1(136)、Replica2:完整同步主库所有数据,默认只读,仅处理 GET/HGET 读请求;

数据流向(137):所有写入仅在主节点生成,异步同步给两台从节点。

3.1.1.2 Redis 主从复制原理

(1) 核心机制: Redis 主从复制是单分片数据多副本架构:一台 Master(主节点)负责所有写操作,多台 Replica(从节点)全量同步主节点数据,只承担读查询,实现读写分离与数据备份。

(2)同步流程:

  • 建立长连接 :从节点启动后,主动向主节点发起 TCP 连接,发送 PSYNC 同步命令,携带自身已同步的偏移量。
  • 全量同步(首次同步 / 缓冲区溢出时触发) :主节点执行 bgsave 在后台生成 RDB 全量数据快照;快照传输期间,主节点新写入数据存入复制环形缓冲区 repl_backlog;从节点接收并加载 RDB 文件,清空自身原有数据。
  • 增量同步: RDB 加载完成后,主节点把缓冲区里缓存的所有写命令持续推送给从节点,从节点逐条回放,追上主节点当前数据。
  • 持续实时同步 :同步完成后保持长连接心跳,主库每一条写入命令都会实时异步发送给从库,持续保持数据副本一致。

(3)核心作用

  • 读写分离:海量读压力分摊至从节点,降低主节点 CPU / 内存压力;
  • 数据多副本备份:主节点磁盘损坏、数据丢失,从节点留存完整数据,防止数据丢失;
  • 故障备用节点:主节点宕机后,可手动将一台从节点提升为新主,恢复写入服务。

(4)Redis 主从原生短板

  • 无自动故障转移:主节点宕机后,Redis 主从本身不会检测故障、自动选新主,必须人工操作或依赖 Sentinel 哨兵组件;
  • 纯异步复制,存在数据丢失风险:主节点写入内存立刻返回客户端,不等从库同步完成,主库断电则缓冲区未同步数据直接丢失;
  • 单分片限制:整套数据只存在一台主节点,受单机内存、CPU 上限制约,海量数据无法横向扩容,分片需要 Redis Cluster。

(5)Redis 主从和 MySQL 主从 核心区别

1. 底层同步机制完全不同

Redis

  • 同步载体:RDB 快照 + 内存环形缓冲区 repl_backlog
  • 缓冲区有固定大小,从库长时间断连、主库写入量大,缓冲区会覆盖旧数据,必须重新全量同步;
  • 无持久化独立日志,同步数据存内存缓冲区,重启缓冲区清空。

MySQL

  • 同步载体:binlog 二进制持久化日志 + relay-log 中继日志;
  • binlog 永久落盘存储,从库断连多久都能基于 GTID / 偏移量断点续传,不会强制全量备份;
  • 事务级同步,完整记录 DDL/DML 事务,支持事务回滚。

2.数据一致性模型差异

Redis

默认纯异步复制,无内置半同步机制,主写完直接响应客户端,从库延迟不可控,宕机极易丢数据。

MySQL

支持半同步复制(semi-sync),主库提交事务后,必须等待至少一台从库接收完 binlog,才返回客户端,大幅降低故障数据丢失概率。

3.事务支持差异

Redis

仅支持单条命令原子性,不支持多命令事务回滚,复制只同步单条指令,不存在事务日志概念。

原子 = 要么全部成功,要么全部失败,中间不会卡一半。 Redis 只对单独一条指令 生效: 比如 set user 100hset info name tom 这种单条命令,执行到一半崩溃,这条指令完全不生效,不会写一半数据。Redis 同步的时候,只会一条一条同步你执行的命令,它根本没有 "事务" 这个概念,不会把多条操作打包成一个整体记录下来。

MySQL

完整支持 ACID 事务,binlog 完整记录每条完整事务,GTID 全局唯一标识每条事务,故障恢复、数据校验精准。

ACID 简单说就是多条操作打包成一个事务,要么全部执行成功,要么一条都不生效

binlog:MySQL 的二进制日志,会把一整个事务的所有 SQL 打包记录,不是零散单条语句;故障恢复时可以完整重放整个事务。

GTID:每一条事务分配一个全球唯一编号,不管主从切换多少次,每个事务都有专属 ID,同步、恢复数据时能精准定位,不会重复同步、漏同步。

4. 适用范围

维度 选用 MySQL 主从 选用 Redis 主从
数据性质 核心持久化业务数据 热点临时缓存、计算中间数据
事务要求 需要 ACID、多操作回滚 仅单条命令原子性,无事务回滚
并发压力 中低并发,复杂查询多 超高并发,简单 KV 读写为主
数据丢失容忍 零容忍,必须强一致 可短暂丢失,缓存能重建
存储介质 磁盘持久化为主 内存读写为主,RDB/AOF 仅兜底
典型功能 多表 JOIN、事务、复杂报表 限流、锁、计数、排行榜、缓存

3.1.2主节点 172.25.254.135 配置

3.1.2.1 复制修改模板配置文件
bash 复制代码
cp /usr/local/src/redis-6.2.14/redis.conf /usr/local/redis/conf/redis-master.conf
#可直接清空复制下来的模板文件
vim /usr/local/redis/conf/redis-master.conf

bind 0.0.0.0           # 允许所有机器访问,哨兵、从库才能连通
port 6379
daemonize yes          # 后台运行
pidfile /usr/local/redis/data/redis-master.pid 
logfile /usr/local/redis/logs/master.log #排错日志
dir /usr/local/redis/data
requirepass 123456     # 客户端连接密码,所有客户端访问必须认证;从库连接主库也需要该密码
masterauth 123456      # 如果后续变从库,同步新主库的密码
# 开启持久化 900s内至少1次写、300s内至少10次写,触发RDB快照保存
save 900 1
save 300 10
# 开启AOF持久化,记录每一条写命令,RDB+AOF双重保障数据安全
appendonly yes
appendfilename "appendonly.aof"
3.1.2.2 启动主Redis
bash 复制代码
redis-server /usr/local/redis/conf/redis-master.conf

验证:

3.1.3 从节点配置(136、137)

3.1.3.1 复制并修改配置文件
bash 复制代码
cp /usr/local/src/redis-6.2.14/redis.conf /usr/local/redis/conf/redis-slave.conf

#两个从节点配置一样
bind 0.0.0.0
port 6379
daemonize yes
pidfile /usr/local/redis/data/redis-slave.pid
logfile /usr/local/redis/logs/slave.log
dir /usr/local/redis/data
requirepass 123456
masterauth 123456
replicaof 172.25.254.135 6379   # 核心:指定主节点IP端口,旧版本写slaveof
save 900 1
save 300 10
appendonly yes
3.1.3.2 启动
bash 复制代码
redis-server /usr/local/redis/conf/redis-slave.conf

3.1.3 主节点验证主从同步

主节点:

从节点1:

从节点2:

如图:Redis的一主二从搭建成功。

3.2 Redis的哨兵模式

3.2.1 哨兵核心定位

基于前文搭建的Redis 一主二从:主负责写、从同步数据、提供读服务,但主宕机后无法自动选新主、修改其余从的复制源 ; Redis 哨兵(Sentinel)是独立运行的特殊 Redis 进程,不存储业务数据,专门做三件事:监控、故障判定、自动故障转移,给原有 Redis 主从加上高可用能力,像 MySQL 里 的MHA 。

3.2.2 哨兵架构

  • 172.25.254.135 Redis 主 + Sentinel1
  • 172.25.254.136 Redis 从 + Sentinel2
  • 172.25.254.137 Redis 从 + Sentinel3

哨兵数量必须为奇数(最少 3 个):用来投票达成多数决议,规避脑裂;3 个哨兵里≥2 个判定主节点故障,才正式触发故障转移。

3.2.3工作流程

(1)监控阶段

每个哨兵会和 Redis 主、从建立 TCP 连接,定时发送PING心跳检测存活状态;哨兵之间也会互相通信,同步各自获取的节点状态。

(2)主观下线、客观下线
  • 主观下线:某一个哨兵 ping 不通主节点,该哨兵单方面标记主节点下线;
  • 客观下线:向其余哨兵发起投票,超过半数哨兵同样认为主节点故障,主节点正式判定为客观下线,启动故障转移。
(3)选举哨兵 leader

所有参与投票的哨兵内部选举出一个领头哨兵,由这个 leader 全权执行后续切换操作,避免多个哨兵同时操作引发混乱。

(4)选举新 Redis 主节点

leader 按照优先级筛选从节点:

  • replica-priority从节点优先级数值越小越优先;
  • 复制偏移量越大,代表同步主库数据越完整,优先选中;
  • 运行 ID 最小的从节点作为兜底; 选中的从节点执行replicaof no one晋升为新主。
(5)更新剩余从节点复制源

剩余旧从节点,自动修改replicaof指向新主,开始同步新主数据。

(6)下线旧主处理

旧主恢复上线后,哨兵自动把它配置为新主的从节点,接入集群。

3.2.4 Redis与MySQL MHA的区别

对比维度 Redis Sentinel MySQL MHA
依托底层复制 Redis 主从复制(RDB + 复制缓冲区增量同步) MySQL binlog 主从复制
管理节点部署 分布式部署,多个 Sentinel 分散在不同服务器,无单独管理机;哨兵之间对等组网 需要独立 MHA Manager 管理机,集群调度集中在管理机
投票机制 哨兵集群内部对等投票,多数派判定故障 MHA Manager 单独检测主从,管理机决策、下发切换指令,没有分布式投票
新主选举依据 从节点复制偏移量、节点优先级 从节点 binlog 日志位点、GTID 完备程度,优先选日志最完整的从库
从库重构 哨兵主动向从节点发送指令,自动修改复制指向新主 MHA 通过 SSH 登录从库,执行 SQL 语句修改复制配置
旧主恢复 旧主重启后自动变为新主从节点 旧主恢复后需要人工或脚本接入新拓扑,MHA 不会自动接入
VIP 漂移 哨兵本身不带 VIP 功能,需要额外编写脚本对接 keepalived 实现 VIP;客户端优先向哨兵查询主地址 MHA 原生支持调用 VIP 漂移脚本,业务通过 VIP 访问,切换后 VIP 漂移,业务无感知
数据丢失容忍 Redis 默认异步复制,极端宕机会丢失少量缓冲区未同步数据;哨兵无法解决该问题 MySQL 可开启半同步复制,MHA 配合半同步大幅降低数据丢失概率
事务适配 Redis 无事务,仅同步单条命令 适配完整事务、GTID,严格保证事务完整性

3.2.5 哨兵搭建流程

3.2.5.1 前置条件

Redis 一主二从已正常运行:135 主、136/137 从;三台服务器都已安装 Redis,redis-sentinel命令可用;主从密码统一为123456

3.2.5.2 三台机器分别创建哨兵配置文件

以172.25.254.135为例,136、137相同:

bash 复制代码
#复制官方模板
cp /usr/local/src/redis-6.2.14/sentinel.conf /usr/local/redis/conf/sentinel.conf

#可清空后粘贴以下配置
bind 0.0.0.0
port 26379
daemonize yes
pidfile /usr/local/redis/data/sentinel.pid
logfile /usr/local/redis/logs/sentinel.log
dir /usr/local/redis/data
# mymaster:主集群自定义名称;最后数字2:判定客观下线至少需要2个哨兵投票同意
sentinel monitor mymaster 172.25.254.135 6379 2
# 主节点认证密码,和requirepass一致
sentinel auth-pass mymaster 123456
# 3000ms(3秒)ping不通,单个哨兵判定主观下线
sentinel down-after-milliseconds mymaster 3000
# 故障转移时,同时向多少个从库发起同步,1代表串行同步,降低新主压力
sentinel parallel-syncs mymaster 1
# 单次故障转移最大超时时间10秒
sentinel failover-timeout mymaster 10000
3.2.5.3 三台机器分别启动哨兵
bash 复制代码
redis-sentinel /usr/local/redis/conf/sentinel.conf
3.2.5.4 校验

先进入哨兵客户端:

bash 复制代码
redis-cli -p 26379

注意:哨兵默认未配置自身密码,无需执行auth;若你给哨兵配置了requirepass才需要认证

1.查询主节点信息( sentinel masters**)**

合格判定:

  • 能看到集群名(mymaster)、主库 IP 端口;
  • num-slaves=2num-other-sentinels=2:说明识别 2 台从库、另外 2 台哨兵,3 台哨兵组网完成。

2.查询从节点列表(sentinel replicas mymaster)

合格判定:能列出两台从机 IP、master-link-status:ok,代表从库复制正常,哨兵可以正常监控从节点。

3.客户端获取主地址验证

执行命令直接获取当前主节点,模拟业务程序向哨兵查询主库:

bash 复制代码
sentinel get-master-addr-by-name mymaster

合格判定:返回主库172.25.254.135 6379,业务可以通过该接口拿到主节点地址。

4.主库宕机,测试自动故障转移(哨兵最核心能力)

关闭 Redis 主节点(172.25.254.135 的 6379 进程)

bash 复制代码
# 方式1优雅关闭
redis-cli -a 123456 -h 172.25.254.135 shutdown
# 方式2查进程kill
ps -ef|grep redis-server
kill 对应主库进程号

等待约 3~10 秒,哨兵内部完成:主观下线→多数派投票客观下线→选举哨兵 leader→挑选新主→修改其余从库复制指向。在任意原先2台从节点登录Redis客户端,执行"sentinel masters"

以下是在172.25.254.136登录并执行sentinel masters的结果:

合格判定:

  • 主节点 IP 变为其中一台从机(136 或 137);
  • num-slaves仍为 2:另一台从机已经同步跟随新主复制; 说明故障转移生效,哨兵搭建成功。

5.原主恢复上线验证

1.在172.25.254.135重新启动 Redis 主实例

  • 开启 Redis 数据库后台进程,监听 6379 端口,负责存储数据、主从复制、持久化;因为配置里daemonize yes(守护进程),启动后直接退回命令行,不会打印持续日志,肉眼看不出有没有成功跑起来,所以需要后续两条命令验证。
  • 用"ps -ef | grep redis-server"检查进程是否真正运行,启动命令执行完成不代表服务一定正常:可能配置错误、端口占用、权限不足,进程启动瞬间就崩溃退出,终端不会报明显错误。这条命令能确认 Redis 进程存活,操作系统层面运行正常
  • 用"redis-cli -a 123456 ping"测试客户端连通性,进程存在不等于服务可用:比如 Redis 进程活着,但密码错误、网络绑定异常、保护模式拦截请求,外部就无法读写数据。这条是应用层校验:确认 Redis 能接收请求、鉴权正常,可以对外提供读写服务,之后哨兵就会探测到该实例,自动把它配置成新主的从节点、同步数据。

2.执行sentinel masters查看集群拓扑

合格判定:原来的主节点会自动降级,成为新主的从节点,加入复制集群,哨兵自动调整拓扑,无需手动配置。

3.在旧主执行info replication查询自身角色

合格判定:role会显示slave,主库地址指向172.25.254.137

4.验证哨兵是否把该节点自动转为从节点

任意一台哨兵机器执行:

bash 复制代码
redis-cli -p 26379
sentinel replicas mymaster

合格判定:172.25.254.135已经出现在从节点列表,master-host是新主172.25.254.137master-link-status:ok

原理:哨兵探测到旧主上线,自动修改它的复制配置,让旧主同步新主数据,集群恢复完整一主二从

5.数据同步测试

登录新主172.25.254.137写入测试数据:

bash 复制代码
redis-cli -a 123456
set testkey hello

再回到本机172.25.254.135查询:

bash 复制代码
get testkey

合格判定:172.25.254.135能拿到hello,代表主从同步链路完全正常。

6.架构恢复

现在是172.25.254.137为主,172.25.254.135为从;要恢复到172.25.254.135为主,172.25.254.137为从的结构

1.在 135 的 Redis 业务实例(端口 6379)调低从节点优先级

bash 复制代码
# 登录135的Redis
redis-cli -a 123456
# 修改运行时优先级,数值越小越优先当选主
config set slave-priority 50
# 将配置持久写入配置文件,重启Redis也不会丢失
config rewrite
# 退出Redis客户端
exit

2.连接本机哨兵服务(端口 26379),手动触发故障转移

bash 复制代码
# 登录本机哨兵进程
redis-cli -p 26379
# 手动发起主从切换
sentinel failover mymaster

哨兵内部选举逻辑:优先挑选slave-priority更小、数据同步完整的从节点,135优先级 50 低于另外两台默认的 100,会被晋升为新主;原主136、从137会自动变更为 135 的从节点。

关键注意事项

  1. config set slave-priority必须在Redis 业务实例 6379执行;sentinel failover必须在哨兵实例 26379执行,两者端口不能混用;
  2. 不需要更换服务器,直接在135一台机器上切换不同端口操作即可;
  3. 整套流程由哨兵托管,后续若 135 故障,哨兵仍可自动把主切到其他节点,保留高可用能力。

3.3 Redis Cluster 集群搭建(分片集群,含多主多从)

3.3.1 介绍Redis Cluster 集群

1.核心概念

Redis Cluster 是 Redis 官方提供的分布式分片集群,解决单机 / 主从 + 哨兵两个核心短板:

  • 主从 + 哨兵:只有 1 套写入主节点,所有业务写流量打在单主,存储、写入性能受单机上限制约,只能做高可用、不能横向扩容;
  • Redis Cluster:把整体存储空间拆分成16384个哈希槽,不同主节点负责一部分槽,写入时按CRC16(key)%16384计算 key 所属槽,路由到对应主节点;每个主可挂载若干从节点,主宕机后集群内部自动完成主从切换,同时实现分片扩容 + 高可用

关键特性:

  • 哈希槽分片:固定 16384 槽,例如 3 主架构:主 1 负责 0-5460、主 2 负责 5461-10922、主 3 负责 10923-16383;新增主节点可迁移槽位实现扩容。
  • 去中心化:所有节点互相通信(集群总线,端口 = 服务端口 + 10000,如 7001 对应集群通信端口 17001),客户端连接任意节点,节点会返回 key 所属正确节点的重定向信息;支持智能客户端直接缓存槽位映射,减少重定向。
  • 主从高可用:每个主至少 1 个从,主故障,集群通过投票推举从升级为主;若某主所有节点全部下线,该槽段数据不可用,整个集群停止写入。
  • 多 key 限制 :只有哈希标签{tag}包裹的 key 会落到同一槽,支持事务、Lua;跨不同槽的多 key 操作默认不支持。
  • 扩容缩容灵活:新增主节点后,手动迁移部分哈希槽;下线节点先迁出所有槽再移除。

与一主二从+哨兵的区别:

架构 写入节点 扩容能力 故障切换主体 适用场景
单主 + 哨兵 仅 1 个主节点 无法横向扩容,只能升级单机配置 哨兵集群 中小流量、不需要超大存储,追求运维简单
Redis Cluster 多个独立主节点分担写入 可新增主节点、迁移槽横向扩容 集群内部节点投票,无独立哨兵组件 大数据量、高并发写入,需要分片 + 高可用

3.3.2 搭建规划

服务器 Redis 实例 角色 服务端口 集群总线端口 说明
172.25.254.135 实例 1 主节点 1 7001 17001 负责一部分哈希槽
172.25.254.136 实例 2 主节点 2 7002 17002 负责一部分哈希槽
172.25.254.137 实例 3 主节点 3 7003 17003 负责一部分哈希槽
MHA 管理机 实例 4 7001 的从节点 7004 17004 主 1 故障时升主
MHA 管理机 实例 5 7002 的从节点 7005 17005 主 2 故障时升主
MHA 管理机 实例 6 7003 的从节点 7006 17006 主 3 故障时升主

架构优势:3 台业务机做主,分担读写;独立 MHA 机器统一存放所有从节点,业务机器宕机不会同时丢失主 + 从,容灾可靠性更高。

3.3.3 搭建前置准备

3.3.1.1 基础环境(所有机器:135、136、137、MHA 管理机)

1.已编译安装 Redis,redis-serverredis-cli全局可用

4台机器均执行:

bash 复制代码
#切换到系统空目录(如/tmp),避免当前目录有同名文件干扰判断
cd /tmp
#能正常输出版本,证明全局生效
redis-server --version && redis-cli -v

如图所示:

2.防火墙放行端口:7001-7006(服务端口)、17001-17006(集群总线端口)

bash 复制代码
firewall-cmd --add-port=7001-7006/tcp --permanent
firewall-cmd --add-port=17001-17006/tcp --permanent
firewall-cmd --reload

3.关闭selinux避免通信拦截

bash 复制代码
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

4. 每个实例创建独立目录(以 7001 为例,7002和7003同理修改数字)

172.25.254.135创建 7001 目录:

bash 复制代码
mkdir -p /usr/local/redis-cluster/7001/{conf,data,logs}

在MHA机(172.25.254.138)创建7004、7005、7006三套目录:

bash 复制代码
# 一次性创建3套完整目录,每套包含conf、data、logs子文件夹
mkdir -p /usr/local/redis-cluster/{7004,7005,7006}/{conf,data,logs}
  • conf:配置文件
  • data:rdb、aof、集群节点信息文件
  • logs:日志

3.3.4 逐个编写实例配置文件(以 7001 为例)

bash 复制代码
vim /usr/local/redis-cluster/7001/conf/redis.conf

port 7001
bind 0.0.0.0
requirepass 123456 # 访问密码
masterauth 123456 # 主从复制认证密码,和requirepass一致
daemonize yes # 后台运行
pidfile /usr/local/redis-cluster/7001/redis.pid
logfile /usr/local/redis-cluster/7001/logs/redis.log
dir /usr/local/redis-cluster/7001/data

# 集群核心配置
cluster-enabled yes # 开启集群模式
cluster-config-file nodes.conf # 集群节点信息文件,自动生成在data目录
cluster-node-timeout 15000 # 节点超时时间,单位毫秒,超时判定节点下线

# 持久化配置
appendonly yes
dbfilename dump.rdb
protected-mode no

其余实例只需要修改四处:portpidfilelogfiledir里的端口号;比如 7002 把所有7001替换为7002,7004 替换为7004

可用scp加sed命令把701的模板推送给另外3台主机并修改为对应端口。

135配置好模板后scp推送给其余主机:

目标主机(以138为例)接收后更改为对应端口:

3.3.5 启动全部 6 个 Redis 实例

以135为例:

bash 复制代码
redis-server /usr/local/redis-cluster/7001/conf/redis.conf

136和137同理,但138要启动3个实例(7004-7006)。

执行ps -ef | grep redis-server,确认 6 个进程都正常运行以135为例,136和137同理:

7001 [cluster] 集群主进程正常运行;原有6379是旧哨兵架构实例,不影响集群

138上的3个实例也正常运行:

3.3.6 创建集群、分配主从关系

1. 创建 3 个主节点

在135-137三台中的一台执行下面命令,-a传入密码:

redis-cli --cluster create 172.25.254.135:7001 172.25.254.136:7002 172.25.254.137:7003 --cluster-replicas 0 -a 123456

终端会提示预估槽分配方案,输入yes确认;此时 3 主节点完成哈希槽拆分:

  • 7001:0-5460
  • 7002:5461-10922
  • 7003:10923-16383

2.逐个给主添加从节点(138 上的三个实例)

先提取三个主节点ID:

bash 复制代码
redis-cli -h 172.25.254.135 -p 7001 -a 123456 cluster nodes

输出第一列长字符串就是节点 ID

给主 1(7001)挂载从 7004(主02挂从05,主03挂从06同理):

bash 复制代码
redis-cli --cluster add-node 172.25.254.138:7004 172.25.254.135:7001 --cluster-slave --cluster-master-id ec04fac4405d75900367ff129bfbc909962896e4 -a 123456

#redis-cli --cluster add-node:集群新增节点的基础指令

#第 1 个 IP 端口 172.25.254.138:7004:待加入集群的新从节点

#第 2 个 IP 端口 172.25.254.135:7001:集群内任意一个已正常工作的老节点,用来和集群通信、完成新增节点的入网校验,只是一个集群接入入口,不代表把从节点挂给它

#--cluster-slave:指定新节点角色为从节点

#--cluster-master-id xxxxxxxx:真正指定主节点的关键参数(通过redis-cli -h 172.25.254.135 -p 7001 -a 123456 cluster nodes查询)

#-a 123456:Redis 访问密码

注意要替换为自己实际的IP和ID!!!!!!!!!

挂载完后用"cluster nodes"查看完整的主从拓扑。

3.3.7 集群状态校验

1. 查看集群整体信息

bash 复制代码
redis-cli -h 172.25.254.135 -p 7001 -a 123456 cluster info

cluster_state:ok代表集群正常可用

2.查看所有主从、槽分配

bash 复制代码
redis-cli -h 172.25.254.135 -p 7001 -a 123456 cluster nodes

可以看到 3 个 master、3 个 slave,每个从绑定对应的主

3.测试写入

bash 复制代码
redis-cli -c -h 172.25.254.135 -p 7001 -a 123456
# -c开启集群自动重定向
set k1 v1

set是 Redis 写入指令,格式set 键(key) 值(value):创建名为k1的键,把内容v1存入这个键。

  • Redis Cluster 固定CRC16(key) % 16384计算 key 所属槽位,这里算出k1对应的槽是12706
  • 当前连接的7001负责槽范围0-5460,不包含127067003负责10923-1638312706属于 7003,于是 7001 向客户端返回MOVED 12706 172.25.254.137:7003,告知客户端正确的节点地址;
  • 因为启动客户端时带了-c,客户端收到MOVED响应后,自动断开和 7001 的交互连接,新建和172.25.254.137:7003的连接,重新发送set k1 v1
  • 7003 接收指令,把k1v1持久化到本机,返回OK给客户端;
  • 客户端后续复用和 7003 的连接,命令提示符更新为172.25.254.137:7003>,接下来你输入的指令默认发给 7003。

-c自动重定向原理:Redis Cluster 的 16384 个哈希槽分散在多个主节点,单个主节点只负责一部分槽。当你操作的 key 不属于当前连接的节点时,服务端会返回MOVED重定向响应;开启-c后客户端会自动切换连接到目标节点、重试原命令,不需要人工手动换节点登录;如果不加-c,客户端只会把MOVED报错打印出来,命令执行失败;

正常返回v1,代表读取链路、主节点数据存储正常;同时这条数据会异步同步到它的从节点7006

3.3.8 高可用故障演练

前置信息:

  • 主:172.25.254.137:7003,从:172.25.254.138:7006;主:172.25.254.135:7001,从:172.25.254.138:7004
  • Redis 集群节点超时默认cluster-node-timeout 15000即 15s,节点失联超过该时长开始投票故障转移
  • 所有查询集群状态命令,可在任意一台机器执行,优先沿用当前172.25.254.135终端

1.主节点 7003 宕机,验证从节点 7006 自动升主

登录137服务器后执行,优雅关闭7003进程:

bash 复制代码
redis-cli -p 7003 -a 123456 
#先登录在再执行shutdown
shutdown

执行完成后,在 137 验证进程已消失:

bash 复制代码
ps -ef | grep redis-server | grep 7003

无对应进程输出,代表主节点已下线。

查看集群节点状态(在 135 原有终端执行):

bash 复制代码
redis-cli -p 7001 -a 123456 cluster nodes

如图:

7006 角色变更、承接哈希槽:

98665f61488cdbf8d57ba85525147273a61454b8 172.25.254.138:7006@17006 master - 0 1784834737000 4 connected 10923-16383

  • 角色字段是master
  • 末尾槽段10923-16383就是原 7003 负责的哈希槽范围,接管完成。

旧主 7003 故障下线:

eaa2a94728a129cb5c506916ecd9ec6152e9a358 172.25.254.137:7003@17003 master,fail - ... disconnected

  • 状态标记fail、连接状态disconnected,集群已经判定该节点故障。

其余主从配对、槽分配都正常:

  • 7001(0-5460)、7002(5461-10922)两个主节点运行正常,各自从节点 7004、7005 保持connected复制; 整个集群依旧覆盖全部 16384 个哈希槽,业务读写不受主节点宕机影响。

验证业务读写正常:

bash 复制代码
redis-cli -c -p 7001 -a 123456
get k1
set k4 v4

能正常读取原有k1、写入新键k4,证明故障切换后业务可用。

重启旧主 7003(回到 137 机器):

bash 复制代码
#重启7003实例
redis-server /usr/local/redis-cluster/7003/conf/redis.conf

启动后稍等几秒,再次查询集群节点:

bash 复制代码
#回到172.25.254.135那台机器执行
redis-cli -p 7001 -a 123456 cluster nodes

执行后就能看到:刚重启的 7003 已经自动成为7006的从节点,集群拓扑恢复完整。

2. 从节点 7004 宕机,验证主节点不受影响、从节点重启自动同步

关闭从节点 7004(登录 MHA 机 172.25.254.138 操作):

bash 复制代码
redis-cli -p 7004 -a 123456 shutdown

验证进程关闭:

bash 复制代码
ps -ef | grep redis-server | grep 7004

没有 7004 进程即为关闭成功。

验证主 7001 业务读写不受影响(135 终端执行):

bash 复制代码
redis-cli -c -p 7001 -a 123456
set test_slave_down 123
get test_slave_down

可以正常读写;Redis 主节点独立承担哈希槽读写,从仅做备份,从宕机不会阻塞主节点服务。

执行cluster nodes

7004 状态变为fail,主 7001 仍正常对外提供服务。

重启从节点 7004(138机执行):

bash 复制代码
redis-server /usr/local/redis-cluster/7004/conf/redis.conf

校验主从同步恢复,等待数秒,执行:

bash 复制代码
#在135机登陆后执行
redis-cli -p 7001 -a 123456 
cluster nodes

7004 状态变回connected,角色为slave,开始从主 7001 同步缺失的数据,复制链路自动恢复;

验证数据完整性:

bash 复制代码
redis-cli -c -p 7001 -a 123456
get test_slave_down

开启集群模式连接:redis-cli -c -p 7001 -a 123456,执行get test_slave_down,客户端自动跳转 7006 取值

4.后续优化

  1. 配置开机自启

给 6 个 Redis 实例编写 systemd 服务单元,服务器重启后自动拉起集群所有节点,避免人工启动。

  1. 关闭命令行密码告警(可选优化)

后续运维改用redis-cli进入后执行auth 123456认证,不再用-a明文传密码,规避日志、历史记录泄露密码的风险。

  1. 完善持久化、日志轮转A调整 AOF 刷盘策略,配置日志切割,防止单日志文件过大;定期备份 RDB/AOF 数据文件。

  2. 开放监控

开启cluster info监控采集,对接 Prometheus 等监控系统,

相关推荐
gwf2162 小时前
磨损均衡算法(Wear Leveling)——SSD如何让每块闪存“公平退休“?
运维·数据库·人工智能·python·嵌入式硬件·算法·智能硬件
AAA@峥2 小时前
CentOS7 源码编译安装 MySQL5.7|SQL 基础操作 + 备份恢复完整实战
运维·数据库·sql·centos
xixingzhe22 小时前
spring ai简单使用skills
数据库·人工智能·spring
Fu2067212 小时前
数据库第三次作业
数据库
qq_297574673 小时前
RuoYi框架二次开发系列(五)性能优化、Redis缓存实战、分布式部署、接口限流与安全加固生产方案
redis·缓存·性能优化
AI多Agent协作实战派3 小时前
AI多Agent协作系统实战(二十三):Agent读HEARTBEAT.md不读AGENTS.md——openclaw的文件加载之谜
前端·数据库·人工智能·uni-app
jun_bai3 小时前
postgresql数据库免安装版安装到windows系统
数据库·postgresql
weixin_538601973 小时前
智能体测开Day33
数据库·oracle
番茄炒鸡蛋加糖3 小时前
Redis--Lua 脚本原子性与滑动窗口限流
数据库·redis·lua