目录
[一、Redis 介绍](#一、Redis 介绍)
[(一) Redis 核心定义 & 本质](#(一) Redis 核心定义 & 本质)
[(二) Redis 核心特质](#(二) Redis 核心特质)
[1. 丰富的数据结构](#1. 丰富的数据结构)
[2. 高性能](#2. 高性能)
[3. 持久化机制](#3. 持久化机制)
[4. 高可用与分布式](#4. 高可用与分布式)
[5. 原子性操作](#5. 原子性操作)
[(三)Redis 典型的应用场景](#(三)Redis 典型的应用场景)
[(四) Redis 与传统数据库的核心区别](#(四) Redis 与传统数据库的核心区别)
[(一) 安装依赖](#(一) 安装依赖)
[(二)Redis 主节点配置](#(二)Redis 主节点配置)
[(三)配置 Redis 从节点](#(三)配置 Redis 从节点)
[(二)Redis 哨兵模式配置](#(二)Redis 哨兵模式配置)
[五、Redis-cluster 集群](#五、Redis-cluster 集群)
一、Redis 介绍
Redis 是当下最主流的开源内存数据库 (也常被称作键值对存储系统),由 Salvatore Sanfilippo 开发,以高性能、丰富的数据结构、多功能性著称,被广泛用于缓存、会话存储、消息队列、实时统计等场景。
(一) Redis 核心定义 & 本质
Redis 的全称是 REmote DIctionary Server(远程字典服务器),你可以把它理解成:
-
一个 "运行在内存里的数据库":数据默认存储在内存中,读写速度极快(单机能达到每秒十几万次操作);
-
一个 "多功能的工具包":不只是简单的键值存储,还支持多种复杂数据结构,能满足不同业务需求;
-
一个 "兼顾持久化的内存库":虽然数据在内存,但支持将数据持久化到硬盘,避免重启后数据丢失。
(二) Redis 核心特质
1. 丰富的数据结构
(Redis 区别于普通缓存的核心)
这是 Redis 最核心的优势,它支持多种原生数据结构,覆盖绝大多数业务场景:
| 数据结构 | 用途举例 |
|---|---|
| String(字符串) | 存储简单值(如用户昵称、商品价格、验证码)、计数器(如文章阅读量) |
| Hash(哈希) | 存储对象(如用户信息:id、name、age),无需序列化,可单独修改某个字段 |
| List(列表) | 实现消息队列、最新消息列表、评论列表(支持头尾操作) |
| Set(集合) | 去重场景(如用户点赞列表)、交集 / 并集 / 差集(如共同好友) |
| Sorted Set(有序集合) | 排行榜(如游戏积分排名、热搜榜),按分数排序且去重 |
| 其他扩展结构 | Geo(地理位置,如附近的人)、BitMap(位图,如签到统计)、HyperLogLog(基数统计,如 UV 统计) |
2. 高性能
-
纯内存操作,避免磁盘 IO 瓶颈,读速约 110000 次 / 秒,写速约 81000 次 / 秒;
-
单线程模型(核心逻辑),避免线程切换开销,同时支持 IO 多路复用,处理并发请求效率高。
3. 持久化机制
解决 "内存数据易丢失" 的问题,提供两种核心方式:
-
RDB(快照):按指定时间间隔,将内存中的数据快照保存到硬盘(适合备份、灾备);
-
AOF(追加日志):记录所有写操作,重启时重新执行日志恢复数据(数据完整性更高);生产环境通常会同时开启,兼顾性能和数据安全。
4. 高可用与分布式
-
主从复制:一台 master(主节点)写数据,多台 slave(从节点)读数据,分担读压力;
-
哨兵(Sentinel):监控主从节点,主节点宕机时自动切换 slave 为新 master,保证高可用;
-
集群(Cluster):将数据分片存储在多个节点,支持水平扩容,解决单节点内存上限问题。
5. 原子性操作
Redis 的所有命令都是原子性的,且支持事务、Lua 脚本,能保证复杂操作的一致性(比如扣库存、抢红包场景)。
(三)Redis 典型的应用场景
-
缓存:最核心用途,缓存热点数据(如商品详情、用户信息),减轻数据库压力;
-
会话存储:存储用户登录态(如 Session),替代传统的服务器本地存储,支持分布式系统;
-
计数器 / 限流器:如文章阅读量、接口限流(用 incr 命令实现,高性能);
-
消息队列:用 List 或 Pub/Sub(发布订阅)实现简单的消息队列(如异步通知);
-
排行榜 / 实时统计:用 Sorted Set 实现热搜榜、游戏积分排名;
-
分布式锁:用 SETNX 命令实现分布式系统中的互斥锁(如秒杀场景)。
(四) Redis 与传统数据库的核心区别
| 维度 | Redis | 传统数据库(MySQL/Oracle) |
|---|---|---|
| 类型 | 内存型 NoSQL | 磁盘型关系型数据库 |
| 存储位置 | 内存 | 磁盘 |
| 速度 | 极快 | 较慢 |
| 数据结构 | key-value、哈希、列表等 | 表(行 + 列) |
| 查询语言 | 简单命令 | 复杂 SQL |
| 事务 | 弱事务 | 强事务(ACID) |
| 数据安全性 | 可能丢数据(依赖配置) | 数据绝对安全 |
| 主要用途 | 缓存、加速、临时数据 | 存储核心业务数据 |
二、Redis安装部署
(一) 安装依赖
作用:安装 Redis 源码编译和运行所需的基础依赖包:
-
make/gcc:源码编译必备工具(Redis 基于 C 语言开发); -
initscripts:提供系统初始化脚本相关支持,兼容传统 sysvinit 服务脚本。
bash
[root@redis-node1 ~]# dnf install make gcc initscripts -y
(二)源码编译Redis
- 下载并解压源码包
从 Redis 官方源下载 7.4.8 版本源码包
bash
[root@redis-node1 ~]# wget https://download.redis.io/releases/redis-7.4.8.tar.gz
[root@redis-node1 ~]# tar zxf redis-7.4.8.tar.gz
[root@redis-node1 ~]# cd redis-7.4.8/
- 编译并安装 Redis
-
make:基于源码的 Makefile 编译 Redis 二进制程序; -
make install:将编译好的redis-server(服务端)、redis-cli(客户端)等程序安装到系统默认路径(通常/usr/local/bin/
bash
[root@redis-node1 redis-7.4.8]# make && make install
- 适配 systemd 系统的安装脚本修改
-
Redis 官方的
install_server.sh脚本默认会检测系统是否为systemd(主流 Linux 系统如 CentOS 7+、RHEL 7 + 均为 systemd),检测到后会直接退出; -
此处注释掉该检测逻辑,目的是让脚本能在 systemd 系统中正常执行(兼容传统 sysvinit 脚本)
bash
[root@redis-node1 redis-7.4.8]# cd utils/
[root@redis-node1 utils]# vim install_server.sh
# 注释掉以下systemd检测逻辑:
#bail if this system is managed by systemd
#_pid_1_exe="$(readlink -f /proc/1/exe)"
#if [ "${_pid_1_exe##*/}" = systemd ]
#then
# echo "This systems seems to use systemd."
# echo "Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
# exit 1
#fi
- 执行安装脚本配置 Redis 服务
执行脚本后会交互式配置 Redis 实例
| 配置项 | 默认值 / 自定义值 | 说明 |
|---|---|---|
| redis port | 6379 | Redis 服务监听端口(默认 6379,可自定义) |
| redis config file | /etc/redis/redis.conf | 自定义配置文件路径(默认/etc/redis/6379.conf,改为统一的redis.conf) |
| redis log file | /var/log/redis_6379.log | 日志文件路径(按端口区分,便于多实例管理) |
| data directory | /var/lib/redis/6379 | 数据存储目录(Redis 持久化文件、缓存数据的存放路径) |
| redis executable path | /usr/local/bin/redis-server | Redis 服务端程序路径(make install默认安装路径) |
脚本执行完成后会:
-
生成
/etc/init.d/redis_6379服务脚本(sysvinit 格式); -
自动将服务添加到 chkconfig(sysvinit 的开机自启管理工具);
-
启动 Redis 服务。
bash
[root@redis-node1 utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] /etc/redis/redis.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379
Config file : /etc/redis/redis.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
- 传统 sysvinit 方式管理 Redis 服务
bash
# 启动/停止服务
[root@redis-node1 utils]# /etc/init.d/redis_6379 start
[root@redis-node1 utils]# /etc/init.d/redis_6379 stop
# 设置开机自启/关闭开机自启(chkconfig是sysvinit工具)
[root@redis-node1 utils]# chkconfig redis_6379 on
[root@redis-node1 utils]# chkconfig redis_6379 off
- 适配 systemd 管理 Redis 服务
bash
# 复制systemd服务模板到系统服务目录
[root@redis-node1 utils]# cp systemd-redis_server.service /lib/systemd/system/redisd.service
# 重新加载systemd配置(修改/新增服务后必须执行)
[root@redis-node2 utils]# systemctl daemon-reload
# 查看/启动服务(systemd方式)
[root@redis-node2 utils]# systemctl status redis_6379.service
[root@redis-node2 utils]# systemctl start redis_6379.service
- 验证 Redis 服务监听
-
netstat -antlpe:查看系统监听的端口(a= 所有,n= 数字格式,t=tcp 协议,l= 监听状态,p= 进程,e= 用户 / 权限); -
输出说明:Redis 服务在
127.0.0.1:6379(IPv4)和::1:6379(IPv6)监听,进程为redis-server,说明服务正常运行。
bash
[root@redis-node2 utils]# netstat -antlpe | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 0 76854 35530/redis-server
tcp6 0 0 ::1:6379 :::* LISTEN 0 76855 35530/redis-server
三、Redis主从复制
(一)核心背景
Redis 主从复制是 Redis 高可用的基础方案:
-
主节点(master):可读写,负责接收客户端的写请求,并将数据同步给从节点;
-
从节点(slave/replica):只读,从主节点同步数据,分担读请求压力,也可作为主节点故障后的备用节点。
(二)Redis 主节点配置
操作对象:redis-node1(172.25.254.10)
-
bind:指定 Redis 监听的 IP,* -::*表示同时监听 IPv4 和 IPv6 的所有地址; -
protected-mode no:关闭保护模式,否则非本机访问会被拒绝(生产环境需结合密码 / IP 白名单,仅测试环境可直接关闭)。
bash
[root@redis-node1 ~]# vim /etc/redis/redis.conf
#bind 127.0.0.1 -::1 # 注释默认绑定本地回环地址(仅本机可访问)
bind * -::* # 修改为绑定所有网卡(允许远程访问)
protected-mode no # 关闭保护模式(默认开启时,仅本机可访问)
# 重启Redis使配置生效
[root@redis-node1 ~]# systemctl restart redis_6379.service
(三)配置 Redis 从节点
操作对象:redis-node2(172.25.254.20)、redis-node3(172.25.254.30),均作为从节点。
bash
[root@redis-node2 ~]# vim /etc/redis/redis.conf
#bind 127.0.0.1 -::1
bind * -::* # 同主节点,允许远程访问
protected-mode no # 关闭保护模式
replicaof 172.25.254.10 6379 # 核心:指定主节点的IP和端口,声明自己是从节点
# 重启生效
[root@redis-node2 ~]# systemctl restart redis_6379.service
(四)查看状态并测试
- 状态查看(验证主从关系是否生效)
(1)主节点(redis-node1)查看
bash
[root@redis-node1 ~]# redis-cli # 进入Redis客户端
127.0.0.1:6379> info replication # 查看复制相关状态
# Replication
role:master # 当前节点是主节点
connected_slaves:2 # 已连接 2 个从节点
slave0:ip=172.25.254.20,port=6379,state=online,offset=391,lag=0 # 第一个从节点的 IP、端口、状态(online = 在线)
slave1:ip=172.25.254.30,port=6379,state=online,offset=391,lag=1 # 第二个从节点信息
master_failover_state:no-failover
master_replid:e5f5cddc017ab0d5223213592d0482b832d3af77
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:391
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:391
(2)从节点(以 redis-node2 为例)查看
bash
[root@redis-node2 ~]# redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave # 当前节点是从节点
master_host:172.25.254.10 # 关联的主节点 IP 和端口
master_port:6379
master_link_status:up # 主从连接状态(up = 正常,down = 断开)
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_read_repl_offset:433
slave_repl_offset:433
slave_priority:100
slave_read_only:1 # 从节点处于只读模式(1 = 开启,0 = 关闭)
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:e5f5cddc017ab0d5223213592d0482b832d3af77
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:433
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:433
- 测试数据同步性(验证主从数据一致性 + 从节点只读特性)
(1)主节点写入数据
bash
[root@redis-node1 ~]# redis-cli
127.0.0.1:6379> set name lee # 写入键值对(name=lee)
OK
127.0.0.1:6379> get name # 读取验证
"lee"
(2)从节点读取数据(验证同步)
bash
[root@redis-node2 ~]# redis-cli
127.0.0.1:6379> get name # 读取主节点写入的name
"lee" # 成功同步
[root@redis-node3 ~]# redis-cli
127.0.0.1:6379> get name
"lee" # 成功同步
(3)从节点写入数据(验证只读)
bash
[root@redis-node3 ~]# redis-cli
127.0.0.1:6379> set test 123
(error) READONLY You can't write against a read only replica. # 报错:只读副本不允许写操作
结论:从节点默认只读,无法写入数据,仅能同步主节点的写操作。
四、Redis哨兵模式
实现 Redis 主从架构的高可用 ------ 当主节点故障时,哨兵自动将从节点提升为新主节点,保障服务不中断。
(一)核心背景
Redis 哨兵模式是 Redis 官方提供的高可用解决方案,核心作用:
-
监控:持续检查主节点(master)和从节点(slave)是否正常运行;
-
自动故障切换:主节点故障时,选举新主节点、将其他从节点指向新主;
-
通知:将故障切换结果通知给应用或运维。
主节点:172.25.254.10(redis-node1)
从节点 1:172.25.254.20(redis-node2)
从节点 2:172.25.254.30(redis-node3)
哨兵监听端口:26379(Redis 默认哨兵端口)
(二)Redis 哨兵模式配置
- 主节点(redis-node1)哨兵配置
bash
# 复制哨兵配置文件到系统配置目录,方便管理
[root@redis-node1 ~]# cd redis-7.4.8/
[root@redis-node1 redis-7.4.8]# cp -p sentinel.conf /etc/redis/
# 编辑哨兵配置文件
[root@redis-node1 redis-7.4.0]# vim /etc/redis/sentinel.conf
protected-mode no #关闭保护模式
port 26379 #监听端口
daemonize no #进入不打入后台
pidfile /var/run/redis-sentinel.pid #sentinel进程pid文件
loglevel notice #日志级别
sentinel monitor mymaster 172.25.254.100 6379 2 #创建sentinel监控监控master主机,2表示必须得到2票
sentinel down-after-milliseconds mymaster 10000 #master中断时长,10秒连不上视为master下线
sentinel parallel-syncs mymaster 1 #发生故障转移后,同时开始同步新master数据的slave数量
sentinel failover-timeout mymaster 180000 #整个故障切换的超时时间为3分钟
bash
[root@redis-node1 ~]# cp -p /etc/redis/sentinel.conf /mnt/
- 从节点基础配置
从节点需关闭保护模式(否则无法和主 / 哨兵通信):
bash
#在从节点关闭protected-mode模式
[root@redis-node2 ~]# vim /etc/redis/redis.conf
protected-mode no
[root@redis-node2 ~]# systemctl restart redis_6379.service
[root@redis-node3 ~]# vim /etc/redis/redis.conf
protected-mode no
[root@redis-node3 ~]# systemctl restart redis_6379.service
- 哨兵配置同步
将主节点的哨兵配置文件同步到所有从节点,保证所有节点的哨兵配置一致:
bash
#在主节点复制sentinel.conf到从节点
[root@redis-node1 ~]# scp /etc/redis/sentinel.conf root@172.25.254.20:/etc/redis/
[root@redis-node1 ~]# scp /etc/redis/sentinel.conf root@172.25.254.30:/etc/redis/
bash
[root@redis-node2 ~]# cp -p /etc/redis/sentinel.conf /mnt/
[root@redis-node3 ~]# cp -p /etc/redis/sentinel.conf /mnt/
- 启动所有节点的哨兵进程
启动后信息解析
-
# +monitor master mymaster 172.25.254.10 6379 quorum 2:哨兵开始监控主节点; -
* +slave slave 172.25.254.20:6379 ...:哨兵发现并监控从节点; -
* +sentinel sentinel ... 172.25.254.20 26379 ...:哨兵集群发现其他节点的哨兵进程(形成哨兵集群)。
bash
# 所有节点执行(redis-node1、2、3)
[root@redis-node1~3 ~]# redis-sentinel /etc/redis/sentinel.conf

(三)测试故障切换
核心目标:模拟主节点(172.25.254.10)故障,验证哨兵自动切换主节点。
- 模拟主节点故障
关闭主节点 Redis 服务
bash
[root@redis-node1 6379]# redis-cli
127.0.0.1:6379> SHUTDOWN
not connected> quit

- 哨兵故障切换日志解析
| 日志关键词 | 含义 |
|---|---|
+sdown master mymaster ... |
单个哨兵判定主节点主观下线(sdown) |
+odown master mymaster ... #quorum 2/2 |
达到仲裁数(2 个哨兵确认),判定主节点客观下线(odown) |
+try-failover master mymaster ... |
开始尝试故障切换 |
+vote-for-leader ... |
哨兵集群投票选举 "故障切换领导者"(负责执行切换) |
+selected-slave slave 172.25.254.20:6379 ... |
选中从节点 20 作为新主节点 |
+failover-state-send-slaveof-noone ... |
向选中的从节点 20 发送指令:取消从节点身份(slaveof no one),提升为主节点 |
+promoted-slave ... 172.25.254.20:6379 ... |
确认从节点 20 升级为新主节点 |
+slave-reconf-sent slave 172.25.254.30:6379 ... |
指令剩余从节点 30:同步新主节点 20 的数据 |
+switch-master mymaster 10:6379 20:6379 |
完成切换:主节点从 10(6379)切换为 20(6379) |
bash
#切换信息
37502:X 08 Mar 2026 17:56:40.872 * Sentinel new configuration saved on disk
37502:X 08 Mar 2026 17:56:40.872 * Sentinel ID is d0780e7fd242a8f3244bc4dbead0fe63f793af03
37502:X 08 Mar 2026 17:56:40.872 # +monitor master mymaster 172.25.254.10 6379 quorum 2
37502:X 08 Mar 2026 17:56:40.873 * +slave slave 172.25.254.20:6379 172.25.254.20 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:56:40.874 * Sentinel new configuration saved on disk
37502:X 08 Mar 2026 17:56:40.874 * +slave slave 172.25.254.30:6379 172.25.254.30 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:56:40.902 * Sentinel new configuration saved on disk
37502:X 08 Mar 2026 17:57:02.726 * +sentinel sentinel ae862a91f4d7dba85c8e23da1c2e3e2758e5741d 172.25.254.20 26379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:57:02.727 * Sentinel new configuration saved on disk
37502:X 08 Mar 2026 17:58:22.387 * +sentinel sentinel 7ef7c9ff4a5c9891530c9bd5f9379a39e5941079 172.25.254.30 26379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:58:22.389 * Sentinel new configuration saved on disk
37502:X 08 Mar 2026 17:59:16.271 # +sdown master mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.338 # +odown master mymaster 172.25.254.10 6379 #quorum 2/2
37502:X 08 Mar 2026 17:59:16.338 # +new-epoch 1
37502:X 08 Mar 2026 17:59:16.338 # +try-failover master mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.340 * Sentinel new configuration saved on disk
37502:X 08 Mar 2026 17:59:16.340 # +vote-for-leader d0780e7fd242a8f3244bc4dbead0fe63f793af03 1
37502:X 08 Mar 2026 17:59:16.342 * 7ef7c9ff4a5c9891530c9bd5f9379a39e5941079 voted for d0780e7fd242a8f3244bc4dbead0fe63f793af03 1
37502:X 08 Mar 2026 17:59:16.343 * ae862a91f4d7dba85c8e23da1c2e3e2758e5741d voted for d0780e7fd242a8f3244bc4dbead0fe63f793af03 1
37502:X 08 Mar 2026 17:59:16.440 # +elected-leader master mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.441 # +failover-state-select-slave master mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.503 # +selected-slave slave 172.25.254.20:6379 172.25.254.20 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.503 * +failover-state-send-slaveof-noone slave 172.25.254.20:6379 172.25.254.20 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.580 * +failover-state-wait-promotion slave 172.25.254.20:6379 172.25.254.20 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.641 * Sentinel new configuration saved on disk
37502:X 08 Mar 2026 17:59:16.641 # +promoted-slave slave 172.25.254.20:6379 172.25.254.20 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.641 # +failover-state-reconf-slaves master mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:16.693 * +slave-reconf-sent slave 172.25.254.30:6379 172.25.254.30 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:17.520 # -odown master mymaster 172.25.254.10 6379 #客观下线
37502:X 08 Mar 2026 17:59:17.674 * +slave-reconf-inprog slave 172.25.254.30:6379 172.25.254.30 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:17.674 * +slave-reconf-done slave 172.25.254.30:6379 172.25.254.30 6379 @ mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:17.746 # +failover-end master mymaster 172.25.254.10 6379
37502:X 08 Mar 2026 17:59:17.746 # +switch-master mymaster 172.25.254.10 6379 172.25.254.20 6379 #主节点被切换到20
- 验证切换结果
在从节点 30 上查看复制状态:
bash
[root@redis-node3 ~]# redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave # 30仍为从节点
master_host:172.25.254.20 # 主节点已切换为20
master_port:6379
master_link_status:up # 和新主节点通信正常
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:123299
slave_repl_offset:123299
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:dcd9e887a20f05380a448cca1f332ec2501e5477
master_replid2:d4caee184d2c8ffdf82d30fc7267ec6cedbf08f8
master_repl_offset:123299
second_repl_offset:113351
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:91236
repl_backlog_histlen:32064

- 恢复原主节点(10)并验证
重启原主节点 10 的 Redis 服务:
bash
[root@redis-node1 6379]# /etc/init.d/redis_6379 start
Starting Redis server...
在新主节点 20 上查看复制状态:
bash
[root@redis-node2 ~]# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master # 20保持主节点身份
connected_slaves:2 # 有2个从节点
slave0:ip=172.25.254.30,port=6379,state=online,offset=130264,lag=1 # 原从节点30
slave1:ip=172.25.254.10,port=6379,state=online,offset=135673,lag=0 # 原主节点10变为从节点,同步新主20的数据
master_failover_state:no-failover
master_replid:dcd9e887a20f05380a448cca1f332ec2501e5477
master_replid2:d4caee184d2c8ffdf82d30fc7267ec6cedbf08f8
master_repl_offset:130405
second_repl_offset:113351
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:91236
repl_backlog_histlen:39170

五、Redis-cluster 集群
(一)修改所有节点配置文件
核心是开启 Redis 节点的集群功能,并配置集群相关参数,为组建集群做准备。
bash
[root@redis-node1 ~]# vim /etc/redis/6379.conf
masterauth "123456" # 集群内主从节点同步时的认证密码(防止未授权访问)
cluster-enabled yes # 开启集群模式(默认关闭,单机模式不启用)
cluster-config-file nodes-6379.conf # 集群节点的配置文件(自动生成,记录节点拓扑、槽位等信息)
cluster-node-timeout 15000 # 节点超时时间(ms):超过该时间无响应则判定节点故障,触发主从切换
# 重启节点前先停止Redis服务
[root@redis-node1 ~]# /etc/init.d/redis_6379 stop # 重启节点前先停止Redis服务(后续需重启生效配置)
注意:该操作需要在所有集群节点(文档中涉及 10/20/30/40/50/60 等 IP 的节点)上执行,确保每个节点都开启集群功能。
(二)启动集群
- 集群创建命令
通过redis-cli --cluster create命令创建集群,核心是指定节点、分配槽位、配置主从关系。
-
--cluster create:指定创建集群的动作; -
后续列出的 6 个
IP:端口:集群包含的所有节点; -
--cluster-replicas 1:指定每个主节点对应 1 个从节点(最终形成 3 主 3 从的集群架构)。
bash
[root@redis-node1 ~]# redis-cli --cluster create 172.25.254.10:6379 172.25.254.20:6379 172.25.254.30:6379 172.25.254.40:6379 172.25.254.50:6379 172.25.254.60:6379 --cluster-replicas 1
- 集群槽位自动分配
Redis 集群的核心是槽位(slot),共 16384 个槽位,数据会根据哈希算法映射到不同槽位,槽位分配决定数据存储的节点:
bash
Master[0] -> Slots 0 - 5460 # 10节点:主节点,负责0-5460槽位
Master[1] -> Slots 5461 - 10922 # 20节点:主节点,负责5461-10922槽位
Master[2] -> Slots 10923 - 16383 #30节点:主节点,负责10923-16383槽位
Adding replica 172.25.254.50:6379 to 172.25.254.10:6379 #50节点是10节点的从节点
Adding replica 172.25.254.60:6379 to 172.25.254.20:6379 #60节点是20节点的从节点
Adding replica 172.25.254.40:6379 to 172.25.254.30:6379 #40节点是30节点的从节点
- 确认配置并完成创建
输入yes确认槽位分配方案,Redis 会自动完成节点握手、集群初始化:
bash
Can I set the above configuration? (type 'yes' to accept): yes
- 集群验证命令
- 查看集群槽位 / 节点 / 数据分布:
bash
[root@redis-node1 ~]# redis-cli --cluster info 172.25.254.10:6379
172.25.254.10:6379 (8db833f3...) -> 0 keys | 5461 slots | 1 slaves.
172.25.254.30:6379 (d9300173...) -> 0 keys | 5461 slots | 1 slaves.
172.25.254.20:6379 (ca599940...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
输出显示每个主节点的槽位数量、从节点数、存储的 key 数量(初始为 0)。
- 查看集群状态详情:
bash
[root@redis-node1 ~]# redis-cli cluster info
cluster_state:ok # 集群状态正常(若为 fail 则集群不可用)
cluster_slots_assigned:16384 # 16384 个槽位全部分配(集群可用的前提)
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6 # 集群内已知节点数为 6(3 主 3 从)
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:168
cluster_stats_messages_pong_sent:163
cluster_stats_messages_sent:331
cluster_stats_messages_ping_received:158
cluster_stats_messages_pong_received:168
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:331
total_cluster_links_buffer_limit_exceeded:0
- 完整检测集群(槽位、主从、覆盖度):
bash
[root@redis-node1 ~]# redis-cli --cluster check 172.25.254.10:6379
172.25.254.10:6379 (8db833f3...) -> 0 keys | 5461 slots | 1 slaves.
172.25.254.30:6379 (d9300173...) -> 0 keys | 5461 slots | 1 slaves.
172.25.254.20:6379 (ca599940...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 172.25.254.10:6379)
M: 8db833f3c3bc6b8f93e87111f13f56d366f833a0 172.25.254.10:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: c939a04358edc1ce7a1c1a44561d77fb402025fd 172.25.254.60:6379
slots: (0 slots) slave
replicates ca599940209f55c07d06951480703bb0a5d8873a
M: d9300173b75149d3056f0ee3edec063f8ec66e9a 172.25.254.30:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: ca599940209f55c07d06951480703bb0a5d8873a 172.25.254.20:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: ba6ef067c63d30c213493eb48d43427015018898 172.25.254.50:6379
slots: (0 slots) slave
replicates 8db833f3c3bc6b8f93e87111f13f56d366f833a0
S: 32d797eb30094b77edb896abcc0b0fc91ccdb4fd 172.25.254.40:6379
slots: (0 slots) slave
replicates d9300173b75149d3056f0ee3edec063f8ec66e9a
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
(三)集群扩容
集群扩容分为「添加主节点→分配槽位→添加从节点」三步,新增 70(主)、80(从)两个节点。
- 添加新主节点
-
第一个参数
172.25.254.70:6379:待加入的新节点; -
第二个参数
172.25.254.10:6379:集群内任意已存在的节点(用于接入集群); -
此时新节点仅加入集群,但无槽位分配(无法存储数据)。
bash
[root@redis-node1 ~]# redis-cli --cluster add-node 172.25.254.70:6379 172.25.254.10:6379
- 为新主节点分配槽位
通过reshard(重新分片)命令将现有槽位迁移到新节点:
bash
[root@redis-node1 ~]# redis-cli --cluster check 172.25.254.10:6379
...
How many slots do you want to move (from 1 to 16384)? 4096 #分配solt的数量
What is the receiving node ID? dfabfe07170ac9b5d20a5a7a70c836877bd64504
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: all #solt来源
Ready to move 4096 slots.
- 为新主节点添加从节点
-
--cluster-slave:指定该节点为从节点; -
--cluster-master-id:指定主节点 ID(70 节点),建立主从关系。
bash
[root@redis-node1 ~]# redis-cli --cluster add-node 172.25.254.80:6379 172.25.254.10:6379 --cluster-slave --cluster-master-id dfabfe07170ac9b5d20a5a7a70c836877bd64504
- 扩容后验证
再次执行check命令,可见集群变为 4 主 4 从,每个主节点均分配 4096 个槽位,所有 16384 个槽位全覆盖。
bash
[root@redis-node1 ~]# redis-cli --cluster check 172.25.254.10:6379
(四)集群缩容
缩容核心是「槽位回迁→删除节点」,文档中移除了 70(主)、80(从)节点,恢复为 3 主 3 从架构。
- 槽位回迁
将 70 节点的 4096 个槽位迁回 10 节点(原主节点):
交互过程说明:
-
How many slots do you want to move? 4096:迁移 70 节点的全部 4096 个槽位; -
What is the receiving node ID? 8db833f3c3bc6b8f93e87111f13f56d366f833a0:接收节点为 10 节点; -
Source node #1: dfabfe07170ac9b5d20a5a7a70c836877bd64504:指定从 70 节点迁移槽位; -
Source node #2: done:结束源节点指定。
bash
[root@redis-node1 ~]# redis-cli --cluster reshard 172.25.254.10:6379
...
How many slots do you want to move (from 1 to 16384)? 4096
What is the receiving node ID? 8db833f3c3bc6b8f93e87111f13f56d366f833a0 #10id
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: dfabfe07170ac9b5d20a5a7a70c836877bd64504 #70id
Source node #2: done
- 删除节点
先删主节点(70),再删从节点(80):
bash
[root@redis-node1 ~]# redis-cli --cluster del-node 172.25.254.10:6379 dfabfe07170ac9b5d20a5a7a70c836877bd64504
[root@redis-node1 ~]# redis-cli --cluster del-node 172.25.254.10:6379 1176ee294e6b5071ca57e93374d04ac22028daed
- 缩容后验证
执行check命令,集群恢复为 3 主 3 从,10 节点重新持有 8192 个槽位,20/30 节点各 4096 个槽位,所有槽位全覆盖。
bash
[root@redis-node1 ~]# redis-cli --cluster check 172.25.254.10:6379
172.25.254.10:6379 (8db833f3...) -> 1 keys | 8192 slots | 1 slaves.
172.25.254.30:6379 (d9300173...) -> 0 keys | 4096 slots | 1 slaves.
172.25.254.20:6379 (ca599940...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 1 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 172.25.254.10:6379)
M: 8db833f3c3bc6b8f93e87111f13f56d366f833a0 172.25.254.10:6379
slots:[0-6826],[10923-12287] (8192 slots) master
1 additional replica(s)
S: c939a04358edc1ce7a1c1a44561d77fb402025fd 172.25.254.60:6379
slots: (0 slots) slave
replicates ca599940209f55c07d06951480703bb0a5d8873a
M: d9300173b75149d3056f0ee3edec063f8ec66e9a 172.25.254.30:6379
slots:[12288-16383] (4096 slots) master
1 additional replica(s)
M: ca599940209f55c07d06951480703bb0a5d8873a 172.25.254.20:6379
slots:[6827-10922] (4096 slots) master
1 additional replica(s)
S: ba6ef067c63d30c213493eb48d43427015018898 172.25.254.50:6379
slots: (0 slots) slave
replicates 8db833f3c3bc6b8f93e87111f13f56d366f833a0
S: 32d797eb30094b77edb896abcc0b0fc91ccdb4fd 172.25.254.40:6379
slots: (0 slots) slave
replicates d9300173b75149d3056f0ee3edec063f8ec66e9a
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
六、总结
-
Redis 集群核心:依赖 16384 个槽位分片存储数据,主节点负责槽位,从节点容灾;
-
扩容逻辑:加主节点→分槽位→加从节点(保证主从高可用);
-
缩容逻辑:迁回槽位→删节点(必须先迁空槽位,否则无法删除主节点);
-
验证核心 :
cluster info看集群状态,--cluster check看槽位 / 主从完整性。