redis配置与优化
文章目录
- Redis 从基础到实战:全维度学习指南
- 总述
- 一、数据库类型对比:关系型 vs 非关系型
- 1. 关系型数据库(SQL)
- 2. 非关系型数据库(NoSQL)
- 3. 关系型与非关系型对比
- 关系型数据库(SQL)与非关系型数据库(NoSQL)全方位对比表
- 二、Redis 简介
- 1. 定义
- 2. 核心特性
- 3. 为什么“快”?
- 4. 学习资源
- 三、Redis 安装与部署
- 1. 安装准备
- 2. 详细安装流程
- 3. 安装后确认
- 4. 配置文件优化(可选)
- 5. 服务控制命令
- 四、Redis 命令工具
- 1. redis-server:Redis 服务启动工具
- 2. redis-cli:Redis 命令行客户端
- 核心语法
- 常用选项
- 使用示例
- 3. redis-benchmark:性能测试工具
- 核心语法
- 关键选项
- 实用示例
- 4. redis-check-rdb / redis-check-aof:持久化文件修复工具
- 基本用法
- 五、Redis 常用命令
- 1. 基础数据操作(键值对)
- `set`:存储键值对
- `get`:获取键值
- 2. 键管理命令
- `keys`:模糊查询键
- `exists`:判断键是否存在
- `del`:删除键
- `type`:查看值类型
- 3. 键重命名
- `rename`:重命名键(覆盖已有目标键)
- `renamenx`:重命名键(不覆盖已有目标键)
- 4. 数据库统计与管理
- `dbsize`:查看当前数据库键数量
- 密码设置与认证
- 5. 多数据库操作
- `select`:切换数据库
- `move`:跨数据库移动键
- 清空数据库
- 六、Redis 高可用方案
- 1. 持久化:数据备份的基础
- 2. 主从复制:读写分离与数据备份
- 3. 哨兵(Sentinel):自动故障转移
- 4. Cluster 集群:分布式存储与负载均衡
- 七、持久化机制
- 1. RDB 持久化(快照模式)
- 1.1 核心特性与案例
- 1.2 触发条件
- 1.2.1 手动触发
- 1.2.2 自动触发(RDB 持久化)
- 1.3 RDB 核心配置
- 1.4 RDB 执行流程
- 1.5 启动时加载
- 1.6 优缺点分析
- 2. AOF 持久化(日志模式)
- 2.1 核心特性与案例
- 2.2 开启 AOF 配置
- 2.3 AOF 执行流程
- 2.3.1 阶段1:命令追加(append)
- 2.3.2 阶段2:文件写入与同步(write + sync)
- 2.3.3 阶段3:文件重写(rewrite)
- (1)重写原理
- (2)触发方式
- (3)重写流程
- 2.4 启动时加载
- 2.5 优缺点分析
- 3. RDB 与 AOF 全方位对比
- 4. 实际应用选择建议
- 总结
Redis 从基础到实战:全维度学习指南
总述
本文围绕 Redis(开源、高性能键值数据库)展开,从数据库类型对比切入,系统讲解 Redis 的核心特性、安装部署、命令工具、常用操作、高可用方案、持久化机制及性能优化策略,最终总结 Redis 在实际应用中的核心价值与关键注意事项,帮助读者从认知到实战全面掌握 Redis 技术。
一、数据库类型对比:关系型 vs 非关系型
明确 Redis 的定位前,需先理解两类数据库的核心差异,为后续 Redis 的学习奠定基础。
1. 关系型数据库(SQL)
- 核心特点:
- 基于表格模型(行+列),数据需符合预设表结构(Schema)
- 使用 SQL 语言进行数据操作,支持复杂查询(联表、子查询等)
- 强事务保证(ACID 特性:原子性、一致性、隔离性、持久性)
- 扩展方式以“纵向扩展”为主(升级服务器硬件,如 CPU、内存)
- 常见产品:MySQL、Oracle、PostgreSQL
- 典型场景:需强事务的业务,如银行转账(A 扣钱与 B 收钱必须同时成功,避免数据不一致)、电商订单支付。
2. 非关系型数据库(NoSQL)
- 核心特点:
- 存储结构灵活(键值对、文档、图结构等),无需固定表结构
- 侧重高并发、高可扩展性,支持海量数据存储
- 扩展方式以“横向扩展”为主(增加服务器节点,分布式部署)
- 事务支持较弱(部分产品支持简化事务,如 Redis 的单命令原子性)
- 常见产品:Redis(键值)、MongoDB(文档)、HBase(列存储)、Memcached(纯内存键值)
- 典型场景:非结构化/半结构化数据存储,如微信聊天消息(含文字、图片、语音,无需固定结构)、抖音热搜榜(需实时排序与高并发访问)。
3. 关系型与非关系型对比
关系型数据库(SQL)与非关系型数据库(NoSQL)全方位对比表
对比维度 | 关系型数据库(SQL) | 非关系型数据库(NoSQL) |
---|---|---|
存储模型 | 基于结构化表格(行+列),数据需按预设表结构(Schema)组织,字段类型/数量固定 | 支持多类型存储(键值对、文档、列存储、图结构等),无固定结构,灵活适配非结构化数据 |
数据一致性 | 严格遵循 ACID 特性(原子性、一致性、隔离性、持久性),支持强数据一致性 | 多数采用最终一致性(BASE 理论),部分支持弱一致性,仅少数产品(如 MongoDB 4.0+)支持有限事务 |
查询能力 | 支持标准 SQL 语言,可实现复杂查询(联表、子查询、聚合函数、索引优化等) | 无统一查询标准,依赖产品专属语法(如 Redis 命令、MongoDB 查询语句),复杂查询能力较弱 |
事务支持 | 完整事务支持,可实现多操作原子性(如银行转账“扣钱+加钱”原子执行) | 事务支持有限,多数仅支持单操作原子性(如 Redis 单命令原子性),复杂事务需业务层实现 |
扩展方式 | 以“纵向扩展”为主(升级 CPU、内存、磁盘等硬件),横向扩展需复杂分库分表方案 | 以“横向扩展”为主(增加服务器节点,分布式部署),支持动态扩容,扩展成本低 |
读写性能 | 单表读写性能稳定,但高并发场景下易受锁机制、磁盘 IO 限制,复杂查询耗时较长 | 高并发读写性能优异(如 Redis 纯内存操作),适合海量数据快速存取,简单查询响应快 |
适用数据量 | 适合中等数据量(GB-TB 级),超大规模数据下需复杂优化(如分库分表) | 原生支持 PB 级海量数据存储,分布式架构可轻松应对数据量增长 |
索引机制 | 支持多字段联合索引、聚簇索引等,索引优化成熟,可提升复杂查询效率 | 索引机制因产品而异(如 Redis 基于键索引、MongoDB 支持文档字段索引),索引功能相对简化 |
常见产品 | MySQL、Oracle、PostgreSQL、SQL Server | Redis(键值)、MongoDB(文档)、HBase(列存储)、Neo4j(图数据库)、Memcached |
典型场景 | 1. 需强事务的核心业务(银行转账、电商订单支付、金融对账) 2. 结构化数据存储(用户信息、商品属性) 3. 复杂查询场景(财务报表、多表关联统计) | 1. 高并发缓存(Redis 存储热点商品、会话信息) 2. 非结构化数据(微信聊天记录、短视频元数据) 3. 实时分析(抖音热搜榜、日志存储) 4. 海量数据存储(用户行为日志、物联网传感器数据) |
维护成本 | 维护成本较高(需关注表结构变更、索引优化、事务日志管理),需专业 DBA 支持 | 维护成本较低(无需预设结构,分布式部署易维护),但需关注数据一致性、节点容错等问题 |
容错性 | 单机容错依赖主从复制(如 MySQL 主从),但故障转移需手动或第三方工具(如 MHA) | 原生支持分布式容错(如 Redis Cluster 主从切换、MongoDB 副本集),故障转移自动化程度高 |
二、Redis 简介
1. 定义
Redis(Remote Dictionary Server)是一款由 C 语言编写、基于内存、支持持久化的高性能键值数据库,主打“快”与“灵活”,广泛用于缓存、会话存储、实时排行榜等场景。
2. 核心特性
- 极致性能:纯内存操作,读性能达 110000 次/秒,写性能达 81000 次/秒
- 丰富数据结构:支持 string(字符串)、list(列表)、hash(哈希)、sets(无序集合)、sorted sets(有序集合)等
- 持久化能力:支持 RDB、AOF 两种持久化方式,避免内存数据丢失
- 原子性:单线程处理命令(Redis 6.0 后网络请求多线程,但数据操作仍单线程),无需处理并发锁问题
- 高可用支持:提供主从复制、哨兵、集群方案,保障服务稳定
- 多语言兼容:支持 Python、Java、Go 等主流编程语言客户端
3. 为什么“快”?
- 纯内存操作:避免磁盘 I/O 延迟(磁盘读写速度远低于内存)
- 单线程模型:减少多线程切换与锁竞争的开销
- I/O 多路复用:通过 epoll/kqueue 等机制,单线程处理大量并发连接
注意:Redis 6.0 新增的“多线程”仅用于处理网络请求(接收、解析命令),核心的数据读写命令仍由单线程执行,避免并发安全问题。
4. 学习资源
- 中文学习站:https://www.tkcnn.com/redis/Getting-started.html
- 官方文档:https://redis.io/docs/latest/get-started/
三、Redis 安装与部署
1. 安装准备
- 环境要求:Linux 系统(如 CentOS 7/8)、GCC 编译工具(Redis 需编译安装)
- 下载地址:http://download.redis.io/releases/(本文以 Redis 5.0.7 为例)
2. 详细安装流程
systemctl stop firewalld
setenforce 0yum install -y gcc gcc-c++ make
tar zxvf redis-5.0.7.tar.gz -C /opt/
cd /opt/redis-5.0.7/
make && make PREFIX=/usr/local/redis install
#由于Redis源码包中直接提供了 Makefile 文件,所以在解压完软件包后,不用先执行 ./configure 进行配置,可直接执行 make 与 make install 命令进行安装。#执行软件包提供的 install_server.sh 脚本文件设置 Redis 服务所需要的相关配置文件
cd /opt/redis-5.0.7/utils
./install_server.sh
...... #一直回车
Please select the redis executable path [] /usr/local/redis/bin/redis-server #需要手动修改为 /usr/local/redis/bin/redis-server ,注意要一次性正确输入-----------------------------------------------------------------------------------------
Selected config:
Port : 6379 #默认侦听端口为6379
Config file : /etc/redis/6379.conf #配置文件路径
Log file : /var/log/redis_6379.log #日志文件路径
Data dir : /var/lib/redis/6379 #数据文件路径
Executable : /usr/local/redis/bin/redis-server #可执行文件路径
Cli Executable : /usr/local/bin/redis-cli #客户端命令工具----------------------------------------------------------------------------------------------------------#把redis的可执行程序文件放入路径环境变量的目录中便于系统识别
ln -s /usr/local/redis/bin/* /usr/local/bin/#当 install_server.sh 脚本运行完毕,Redis 服务就已经启动,默认监听端口为 6379
netstat -natp | grep redis
3. 安装后确认
脚本执行完成后,Redis 服务默认启动,关键路径如下:
类型 | 路径 |
---|---|
配置文件 | /etc/redis/6379.conf |
日志文件 | /var/log/redis_6379.log |
数据存储目录 | /var/lib/redis/6379 |
可执行文件 | /usr/local/redis/bin/redis-server |
客户端工具 | /usr/local/bin/redis-cli |
4. 配置文件优化(可选)
编辑 /etc/redis/6379.conf
,调整关键参数(需重启服务生效):
vim /etc/redis/6379.conf
# 70行:指定监听IP(允许外部访问,如添加服务器内网IP 192.168.10.23)
bind 127.0.0.1 192.168.10.23
# 93行:默认端口(保持6379即可)
port 6379
# 137行:启用守护进程(后台运行)
daemonize yes
# 159行:PID文件路径
pidfile /var/run/redis_6379.pid
# 167行:日志级别(notice为默认,生产环境可保留)
loglevel notice
# 172行:日志文件路径
logfile /var/log/redis_6379.log
# (可选)添加密码:requirepass 123456(生产环境建议设置)/etc/init.d/redis_6379 restart
5. 服务控制命令
# 启动
/etc/init.d/redis_6379 start
# 停止
/etc/init.d/redis_6379 stop
# 重启
/etc/init.d/redis_6379 restart
# 查看状态
/etc/init.d/redis_6379 status
# 验证端口(默认6379)
netstat -natp | grep redis
四、Redis 命令工具
Redis 提供多款命令工具,覆盖服务启动、客户端连接、性能测试、文件修复等场景,核心工具如下:
工具名称 | 作用 | 常用语法示例 |
---|---|---|
redis-server | 启动 Redis 服务 | redis-server /etc/redis/6379.conf(指定配置文件启动) |
redis-cli | Redis 命令行客户端 | redis-cli -h 192.168.10.23 -p 6379 -a 123456(-h=IP,-p=端口,-a=密码) |
redis-benchmark | 性能测试工具 | redis-benchmark -c 100 -n 100000(100并发,10万请求) |
redis-check-rdb/redis-check-aof | 修复损坏的 RDB/AOF 持久化文件 | redis-check-rdb /var/lib/redis/6379/dump.rdb(检查并修复RDB文件) |
1. redis-server:Redis 服务启动工具
作用:用于启动 Redis 服务进程,负责加载配置文件、初始化内存数据库、监听端口并处理客户端请求。
基本用法:
# 直接启动(使用默认配置)
redis-server# 指定配置文件启动(推荐,生产环境必用)
redis-server /etc/redis/6379.conf
说明:
启动时需指定配置文件(如 /etc/redis/6379.conf
),以确保服务按预设参数(端口、持久化策略、内存限制等)运行。启动成功后,Redis 会监听配置文件中指定的端口(默认 6379)。
2. redis-cli:Redis 命令行客户端
作用:交互式命令行工具,用于连接 Redis 服务、执行操作命令(如增删改查、配置修改等)。
核心语法
redis-cli [选项]
常用选项
选项 | 含义 | 示例 |
---|---|---|
-h | 指定连接的 Redis 服务器 IP 地址(默认 127.0.0.1) | redis-cli -h 192.168.10.23 |
-p | 指定连接的端口号(默认 6379) | redis-cli -p 6380 |
-a | 指定认证密码(若 Redis 配置了密码) | redis-cli -a 123456 |
无选项 | 默认连接本地 127.0.0.1:6379 | redis-cli |
使用示例
# 连接本地 Redis(默认配置)
redis-cli
127.0.0.1:6379> get teacher # 执行命令# 连接远程 Redis 并认证
redis-cli -h 192.168.10.23 -p 6379 -a 123456
192.168.10.23:6379> keys * # 查看所有键
3. redis-benchmark:性能测试工具
作用:官方自带的性能测试工具,用于模拟多客户端并发请求,评估 Redis 服务的吞吐量(如每秒处理请求数)和响应速度,适用于压测场景(如秒杀活动前验证 Redis 承载能力)。
核心语法
redis-benchmark [选项] [选项值]
关键选项
选项 | 含义 |
---|---|
-h | 目标 Redis 服务器 IP(默认 127.0.0.1) |
-p | 目标端口(默认 6379) |
-c | 并发客户端数量(默认 50) |
-n | 总请求数(默认 100000) |
-d | SET/GET 操作的值大小(字节,默认 3) |
-t | 指定测试的命令(如 set,lpush,多个用逗号分隔) |
-q | 仅输出关键结果(每秒请求数),简化输出 |
-l | 循环测试(无限执行,需手动终止) |
实用示例
# 1. 测试远程 Redis 性能:100 并发,10 万请求
redis-benchmark -h 192.168.10.23 -p 6379 -c 100 -n 100000# 2. 测试存取 100 字节数据的性能(仅显示关键结果)
redis-benchmark -h 192.168.10.23 -p 6379 -q -d 100# 3. 仅测试 set 和 lpush 命令的性能
redis-benchmark -t set,lpush -n 100000 -q# 4. 模拟秒杀场景:1000 并发,持续压测(需 Ctrl+C 终止)
redis-benchmark -c 1000 -l -t set
4. redis-check-rdb / redis-check-aof:持久化文件修复工具
作用:用于检查和修复损坏的 RDB 或 AOF 持久化文件(如服务器意外宕机可能导致文件损坏),保障数据恢复时的完整性。
基本用法
# 检查并修复 RDB 文件(如 dump.rdb)
redis-check-rdb /var/lib/redis/6379/dump.rdb# 检查并修复 AOF 文件(如 appendonly.aof)
redis-check-aof /var/lib/redis/6379/appendonly.aof
说明:
若文件轻微损坏(如末尾不完整),工具会自动修复并输出修复结果;若损坏严重,可能需要结合备份文件恢复,修复后建议测试文件可用性(启动 Redis 加载文件验证)。
这些工具覆盖了 Redis 从启动、连接、测试到维护的全流程,掌握其用法是日常运维和开发的基础。
五、Redis 常用命令
Redis 提供了丰富的命令用于数据操作、管理和配置,以下按功能分类详解常用命令,包含语法、示例、返回值及实际应用场景。
1. 基础数据操作(键值对)
set
:存储键值对
功能:向 Redis 中存储一个键值对,支持多种扩展参数(如过期时间、条件设置)。
语法:set key value [EX seconds] [PX milliseconds] [NX|XX]
EX seconds
:设置过期时间(秒),到期后键自动删除PX milliseconds
:设置过期时间(毫秒)NX
:仅当键不存在时才设置(Not Exist)XX
:仅当键存在时才更新(Exist)
示例:
# 基础用法:存储键name,值为"zhangsan"
127.0.0.1:6379> set name zhangsan
OK# 设置过期时间:键token 1小时后过期
127.0.0.1:6379> set token abc123 EX 3600
OK# 条件设置:仅当键count不存在时,设置其值为100(分布式锁常用)
127.0.0.1:6379> set count 100 NX
OK # 键不存在,设置成功
127.0.0.1:6379> set count 200 NX
(nil) # 键已存在,设置失败
返回值:OK
(成功)或 (nil)
(条件不满足时)
get
:获取键值
功能:获取指定键对应的value,若键不存在返回(nil)
。
语法:get key
示例:
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> get age
"20" # 返回值(字符串类型)127.0.0.1:6379> get non_exist_key
(nil) # 键不存在
应用场景:缓存查询(如获取用户信息、商品详情)。
2. 键管理命令
keys
:模糊查询键
功能:根据通配符匹配符合规则的所有键,支持*
(任意字符)、?
(单个字符)。
语法:keys pattern
示例:
# 准备数据
127.0.0.1:6379> set user:1:name tom
127.0.0.1:6379> set user:2:name jerry
127.0.0.1:6379> set product:100 price 99# 匹配所有键
127.0.0.1:6379> keys *
1) "user:1:name"
2) "user:2:name"
3) "product:100"# 匹配以user:开头的键
127.0.0.1:6379> keys user:*
1) "user:1:name"
2) "user:2:name"# 匹配user:X:name(X为单个字符)
127.0.0.1:6379> keys user:?:name
1) "user:1:name"
2) "user:2:name"
注意:
keys
命令会遍历所有键,在数据量大(10万+键)时会阻塞Redis,建议生产环境用scan
替代(渐进式遍历,不阻塞服务)。scan
基本用法:scan 0 match user:* count 10
(从游标0开始,匹配user:*,每次遍历10个键)。
exists
:判断键是否存在
功能:检查指定键是否存在,返回存在的键数量(支持同时检查多个键)。
语法:exists key1 [key2 ...]
示例:
127.0.0.1:6379> set a 10
OK# 检查单个键
127.0.0.1:6379> exists a
(integer) 1 # 存在(返回1)# 检查多个键
127.0.0.1:6379> exists a b c
(integer) 1 # 仅a存在127.0.0.1:6379> exists non_exist_key
(integer) 0 # 不存在
应用场景:检查缓存是否命中(如判断商品信息是否在缓存中)。
del
:删除键
功能:删除指定键,返回成功删除的键数量(忽略不存在的键)。
语法:del key1 [key2 ...]
示例:
127.0.0.1:6379> set x 100
OK
127.0.0.1:6379> set y 200
OK# 删除单个键
127.0.0.1:6379> del x
(integer) 1 # 成功删除1个键# 删除多个键
127.0.0.1:6379> del y z
(integer) 1 # 仅y存在并被删除,z不存在127.0.0.1:6379> get x
(nil) # 已删除
type
:查看值类型
功能:返回键对应的value类型(Redis支持string、hash、list、set、zset等类型)。
语法:type key
示例:
127.0.0.1:6379> set str "hello"
OK
127.0.0.1:6379> hset hash name "redis" # 哈希类型
(integer) 1
127.0.0.1:6379> lpush list 1 2 3 # 列表类型
(integer) 3127.0.0.1:6379> type str
string
127.0.0.1:6379> type hash
hash
127.0.0.1:6379> type list
list
3. 键重命名
rename
:重命名键(覆盖已有目标键)
功能:将源键重命名为目标键,若目标键已存在则直接覆盖。
语法:rename source_key target_key
示例:
127.0.0.1:6379> set old_name "tom"
OK
127.0.0.1:6379> set new_name "jerry" # 目标键已存在
OK127.0.0.1:6379> rename old_name new_name
OK127.0.0.1:6379> get new_name
"tom" # 目标键被覆盖
127.0.0.1:6379> get old_name
(nil) # 源键已删除
风险提示:可能覆盖已有数据,建议先通过 exists target_key
检查目标键是否存在。
renamenx
:重命名键(不覆盖已有目标键)
功能:仅当目标键不存在时,才将源键重命名为目标键(避免覆盖)。
语法:renamenx source_key target_key
示例:
127.0.0.1:6379> set user "old"
OK
127.0.0.1:6379> set customer "existing" # 目标键已存在
OK# 目标键存在,重命名失败
127.0.0.1:6379> renamenx user customer
(integer) 0 # 返回0表示失败# 目标键不存在,重命名成功
127.0.0.1:6379> renamenx user new_customer
(integer) 1 # 返回1表示成功
127.0.0.1:6379> get new_customer
"old"
应用场景:业务名称调整(如“用户”改“客户”)时,避免覆盖已有数据。
4. 数据库统计与管理
dbsize
:查看当前数据库键数量
功能:返回当前数据库中键的总数(O(1)操作,高效,不遍历所有键)。
语法:dbsize
示例:
127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> set b 2
OK
127.0.0.1:6379> dbsize
(integer) 2 # 当前库有2个键
密码设置与认证
Redis 可通过密码限制访问,保障数据安全。
命令 | 功能 | 示例 |
---|---|---|
config set requirepass <password> | 设置密码 | config set requirepass 123456 |
config get requirepass | 查看密码(需先认证) | auth 123456 后执行 config get requirepass |
auth <password> | 密码认证(连接后或密码修改后需执行) | auth 123456 |
示例:
# 设置密码
127.0.0.1:6379> config set requirepass 123456
OK# 未认证时执行命令会报错
127.0.0.1:6379> get a
(error) NOAUTH Authentication required.# 认证后操作
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "123456" # 显示密码
注意:通过 config set
设置的密码是临时的,重启Redis后失效;永久生效需在配置文件(如 redis.conf
)中设置 requirepass 123456
。
5. 多数据库操作
Redis 默认包含16个数据库(编号0-15),相互独立(数据不共享),可通过配置文件 databases <num>
修改数量。
select
:切换数据库
功能:切换到指定编号的数据库(默认使用0号库)。
语法:select <db_index>
示例:
# 切换到1号库
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> # 提示符显示当前库编号# 切换回0号库
127.0.0.1:6379[1]> select 0
OK
move
:跨数据库移动键
功能:将当前库的键移动到目标库,若目标库已存在同名键则移动失败。
语法:move key <target_db_index>
示例:
# 在0号库创建键test
127.0.0.1:6379> set test "move me"
OK# 将test从0号库移动到2号库
127.0.0.1:6379> move test 2
(integer) 1 # 移动成功# 0号库中test已删除
127.0.0.1:6379> get test
(nil)# 切换到2号库,test存在
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> get test
"move me"
清空数据库
命令 | 功能 | 风险 |
---|---|---|
flushdb | 清空当前数据库的所有键 | 仅影响当前库,风险较低 |
flushall | 清空所有数据库的所有键 | 影响所有库,生产环境慎用! |
示例:
# 清空当前库(0号库)
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> dbsize
(integer) 0 # 已清空# 清空所有库(谨慎使用)
127.0.0.1:6379> flushall
OK
应用场景:测试环境清理数据(用flushdb
隔离测试库);生产环境建议禁用flushall
,或通过配置限制权限。
以上命令覆盖了Redis日常使用的核心场景,掌握这些命令是进行数据操作和运维的基础。实际使用中,需结合业务场景选择合适的命令(如缓存过期用set EX
,分布式锁用set NX
),并注意高并发场景下的性能影响(如避免keys *
)。
六、Redis 高可用方案
高可用的核心目标是“服务不中断、数据不丢失”,Redis 提供四层高可用能力,从基础到复杂逐步递进:
1. 持久化:数据备份的基础
- 定义:将内存中的数据写入磁盘,避免进程退出或服务器宕机导致数据丢失(是高可用的“基石”,严格来说是“数据安全”手段,而非“服务容错”)。
- 核心价值:断电后数据可恢复,支持单机数据备份。
- 实现方式:RDB 与 AOF(详见第七章)。
2. 主从复制:读写分离与数据备份
- 架构:一主(Master)多从(Slave),主库负责“写操作”,从库负责“读操作”。
- 核心机制:主库将数据变更同步到从库,从库被动接收并存储,不主动写数据。
- 优势:
- 分担读压力(如秒杀活动中,用户查询热搜走从库)
- 从库可作为主库的备份,避免主库单点故障导致数据丢失
- 缺陷:
- 主库宕机后,需手动切换从库为新主库,服务中断
- 写操作仍集中在主库,无法负载均衡
- 存储能力受限于主库单机内存
场景:微博热搜——主库接收“热搜热度更新”(写),多个从库响应“用户查询热搜”(读),减轻主库压力。
3. 哨兵(Sentinel):自动故障转移
- 架构:在主从复制基础上,增加“哨兵节点”(通常 3 个及以上,避免哨兵单点故障)。
- 核心能力:
- 监控:实时检测主库、从库的健康状态
- 自动故障转移:主库宕机后,哨兵投票选举一个从库升级为新主库,无需人工干预
- 通知:故障转移后,通知客户端更新主库地址
- 优势:解决主从复制“手动切换”的问题,实现服务自动容错
- 缺陷:
- 写操作仍集中在主库,无法横向扩展
- 存储能力受限于主库单机内存
场景:电商订单缓存——主库宕机后,哨兵在 10 秒内自动将从库切换为主库,订单查询/创建业务不中断。
4. Cluster 集群:分布式存储与负载均衡
- 架构:多主多从(至少 3 主 3 从),数据按“哈希槽”(共 16384 个)分片存储到不同主库。
- 核心机制:
- 每个主库负责一部分哈希槽(如主库 1 负责 0-5460,主库 2 负责 5461-10922)
- 客户端根据“键的哈希值”计算所属槽位,直接访问对应主库
- 每个主库搭配从库,实现故障自动转移
- 优势:
- 写操作负载均衡(多主库分担写压力)
- 存储能力横向扩展(增加主库节点即可扩展内存)
- 支持自动故障转移,服务高可用
- 缺陷:架构复杂,部署与维护成本高于哨兵
场景:淘宝商品缓存——商品数据按“商品 ID 哈希”分片到 5 个主库,每个主库存储某类商品的缓存,避免单机内存不足,同时支持多主写操作。
七、持久化机制
Redis 作为内存数据库,若仅将数据存储在内存中,服务器宕机或进程退出会导致数据丢失。持久化的核心作用是将内存数据写入磁盘,保障数据安全性,Redis 提供两种持久化方案:RDB(快照模式)和 AOF(日志模式),二者各有优劣,可单独使用或结合部署。
1. RDB 持久化(快照模式)
RDB 是 Redis 默认的持久化方式,原理是定期将内存中的全量数据生成二进制快照文件(dump.rdb
)写入磁盘,类似“给数据拍一张定时照片”,适用于全量备份场景。
1.1 核心特性与案例
- 定义:通过“快照”记录某一时刻的全量数据,而非实时记录每一次操作;快照文件为二进制格式,体积小、读写效率高。
- 类比案例:手机云备份每天凌晨 2 点自动备份照片——对应 RDB 定期(如 5 分钟)生成数据快照,即使手机丢失,可通过最新快照恢复照片。
1.2 触发条件
RDB 触发分为手动触发和自动触发,均优先通过 bgsave
实现(避免阻塞主进程)。
1.2.1 手动触发
通过命令主动生成 RDB 文件,核心是 save
和 bgsave
两个命令,二者差异显著:
命令 | 执行逻辑 | 阻塞情况 | 适用场景 |
---|---|---|---|
save | 主进程直接生成 RDB 文件,全程参与文件写入 | 阻塞所有客户端命令 | 禁用(仅测试环境临时用) |
bgsave | 主进程 fork 子进程,由子进程生成 RDB 文件,主进程继续处理客户端请求 | 仅 fork 子进程时阻塞 | 线上环境首选 |
示例:
127.0.0.1:6379> bgsave # 手动触发RDB,主进程不阻塞
Background saving started # 提示子进程启动,主进程可继续处理命令
1.2.2 自动触发(RDB 持久化)
RDB 自动触发的核心逻辑是避免阻塞主进程,因此无论哪种触发场景,Redis 都会优先选择 bgsave
(而非 save
)执行持久化。自动触发主要分为「基于配置文件的规则触发」和「特定业务场景触发」两类,以下详细说明:
核心触发方式:配置文件 save m n
规则
这是 RDB 自动触发最常用的方式,通过在 Redis 配置文件中定义 save m n
规则,指定“在 m
秒内,若数据发生至少 n
次变更,则自动执行 bgsave
生成 RDB 快照”。
1. 配置文件路径与默认规则
Redis 配置文件默认路径为 /etc/redis/6379.conf
(若安装时未修改),文件中默认预设 3 条 save
规则,满足任意一条即可触发 bgsave
,覆盖不同数据变更频率的场景:
配置规则 | 含义(m 秒内 n 次变更) | 适用场景 |
---|---|---|
save 900 1 | 900 秒(15 分钟)内 ≥1 次变更 | 低变更频率场景(如用户基础信息) |
save 300 10 | 300 秒(5 分钟)内 ≥10 次变更 | 中变更频率场景(如商品库存) |
save 60 10000 | 60 秒(1 分钟)内 ≥10000 次变更 | 高变更频率场景(如秒杀库存扣减) |
示例配置查看:
# 编辑配置文件,定位到 save 规则(约 219 行)
vim /etc/redis/6379.conf
# 显示内容如下
save 900 1
save 300 10
save 60 10000
2. 规则生效逻辑
- “或”逻辑触发:3 条默认规则互不冲突,只要满足其中任意一条(如“15 分钟内 1 次变更”或“1 分钟内 1 万次变更”),就会立即执行
bgsave
。 - 重置计时:每次数据变更会重置对应规则的计时。例如,若触发
save 60 10000
规则,当 60 秒内已发生 9999 次变更时,若超过 60 秒未达 10000 次,则计时重置,需重新累计。 - 配置修改与生效:若自定义
save
规则(如添加save 120 5
),需重启 Redis 或执行config rewrite
命令(将临时配置写入文件)才能生效。
3. 其他自动触发场景
除 save m n
规则外,Redis 在两种特定业务场景下也会自动执行 bgsave
,无需手动配置:
主从复制:从节点全量同步触发
在 Redis 主从复制架构中,当以下情况发生时,主节点会自动执行 bgsave
:
- 从节点首次连接主节点:从节点需获取主节点的全量数据,主节点会执行
bgsave
生成 RDB 文件,发送给从节点作为初始数据。 - 从节点因网络中断重连后,数据差异过大:若从节点与主节点断开时间较长,从节点的增量数据无法覆盖差异,主节点会再次执行
bgsave
,用新 RDB 文件同步全量数据。
核心目的:通过 RDB 文件实现主从节点的高效数据同步,避免主节点直接传输内存数据导致的网络压力。
2. 执行 shutdown
命令:服务关闭触发
当执行 redis-cli shutdown
命令关闭 Redis 服务时,Redis 会自动触发 RDB 持久化(前提是 AOF 未开启或 AOF 配置失效):
- 执行逻辑:
shutdown
命令会先检查 AOF 是否开启——若 AOF 未开启,则自动执行save
(而非bgsave
)生成 RDB 文件,确保内存数据完全写入磁盘后再关闭服务。 - 特殊情况:若 AOF 已开启,
shutdown
命令会优先触发 AOF 同步(将aof_buf
中剩余命令刷盘),而非 RDB 持久化。
核心目的:避免服务关闭时内存数据丢失,保障数据安全性。
5. 自动触发的关键注意事项
- 避免并发阻塞:
bgsave
执行期间,若再次触发自动触发条件(如save 60 10000
刚执行完,1 分钟内又达 1 万次变更),Redis 会忽略新的触发请求,直到当前bgsave
完成(防止多个子进程并发写盘导致 IO 瓶颈)。 - 性能影响点:
bgsave
的fork
子进程阶段会短暂阻塞主进程(阻塞时间与内存大小相关,通常为毫秒级),高并发场景下需避免在业务高峰期触发(可通过调整save m n
规则规避)。 - 配置优先级:AOF 优先级高于 RDB——若 AOF 已开启,
save m n
规则仍会生效,但 Redis 启动时会优先加载 AOF 文件恢复数据,RDB 文件仅作为备份。
1.3 RDB 核心配置
RDB 的关键配置集中在 /etc/redis/6379.conf
,需理解各参数作用:
配置项 | 含义 | 默认值 |
---|---|---|
dbfilename | RDB 快照文件名 | dump.rdb |
dir | RDB 文件和 AOF 文件的存储目录 | /var/lib/redis/6379 |
rdbcompression | 是否压缩 RDB 文件(压缩会消耗 CPU,但减少磁盘占用) | yes (开启) |
rdbchecksum | 是否对 RDB 文件进行校验(防止文件损坏,轻微消耗 CPU) | yes (开启) |
示例:若需修改 RDB 文件路径为 /data/redis/snapshots,需同步调整 dir 参数并授权:vim /etc/redis/6379.conf
dir /data/redis/snapshots # 修改存储目录
dbfilename redis_6379.rdb # 自定义文件名# 创建目录并授权
mkdir -p /data/redis/snapshots
chown redis:redis /data/redis/snapshots# 重启 Redis 使配置生效
/etc/init.d/redis_6379 restart
1.4 RDB 执行流程
bgsave
是 RDB 的核心执行方式,流程需关注“阻塞点”和“数据一致性”,具体步骤如下:
- 判断前置条件:主进程先检查是否存在正在执行的
save
/bgsave
/bgrewriteaof
子进程(避免并发磁盘 IO 冲突),若存在则直接返回。 - 创建子进程:主进程执行
fork
操作生成子进程,此过程主进程会阻塞(阻塞时间取决于内存大小,通常毫秒级),无法处理客户端命令。 - 主进程恢复服务:
fork
完成后,主进程立即返回“Background saving started”,恢复客户端命令处理,子进程独立负责 RDB 生成。 - 子进程生成快照:子进程读取主进程内存数据,按二进制格式生成临时 RDB 文件(避免覆盖旧文件),生成完成后用临时文件原子替换旧
dump.rdb
(确保文件完整性)。 - 通知主进程:子进程发送信号告知主进程 RDB 完成,主进程更新统计信息(如
info persistence
中的rdb_last_save_time
)。
1.5 启动时加载
RDB 文件的加载是自动执行的,无需手动命令,但需遵循“优先级规则”和“完整性校验”:
- 加载优先级:AOF 优先级高于 RDB——若 AOF 开启且
appendonly.aof
文件存在,Redis 优先加载 AOF 文件;仅当 AOF 关闭或 AOF 文件不存在时,才加载 RDB 文件。 - 加载过程:加载期间 Redis 处于阻塞状态(无法处理客户端命令),直到数据完全载入内存;若 RDB 文件损坏(如磁盘错误),Redis 启动失败,日志会打印“Bad RDB format”错误。
1.6 优缺点分析
优点 | 缺点 |
---|---|
快照文件为二进制,体积小,网络传输快(适合主从全量复制) | 非实时持久化,可能丢失“最后一次快照到宕机”的数据(如 60 秒内未触发快照,宕机丢失 60 秒数据) |
数据恢复速度快(直接加载二进制文件,无需重放命令) | 兼容性差:老版本 Redis 无法加载新版本 RDB 文件 |
对主进程性能影响小(仅 fork 时阻塞,子进程负责写盘) | fork 子进程会占用与主进程相同的内存(内存不足时可能触发 OOM) |
2. AOF 持久化(日志模式)
AOF(Append Only File)与 RDB 原理不同:不记录数据快照,而是将每一条写命令(如 set
/del
,查询命令不记录)按执行顺序追加到日志文件(appendonly.aof
),重启时通过“重放日志中的命令”恢复数据,类似“记账本逐笔记录每一笔开销”。
由于 AOF 支持“秒级数据持久化”,数据丢失风险远低于 RDB,已成为生产环境主流持久化方案。
2.1 核心特性与案例
- 定义:以纯文本格式记录写命令,实时性可通过“同步策略”控制,默认每秒同步一次,最多丢失 1 秒数据。
- 类比案例:会计记账本逐笔记录每一笔收支——对应 AOF 记录每一次写操作,即使账本中间有几页损坏,仍可通过前面的记录恢复大部分数据。
2.2 开启 AOF 配置
Redis 默认关闭 AOF,需修改配置文件 /etc/redis/6379.conf
开启,关键配置如下:
vim /etc/redis/6379.conf
# 700行:开启AOF(默认no,改为yes)
appendonly yes
# 704行:AOF日志文件名(默认appendonly.aof)
appendfilename "appendonly.aof"
# 796行:AOF文件尾部不完整时是否忽略(默认yes,避免启动失败)
aof-load-truncated yes# 配置生效需重启Redis
/etc/init.d/redis_6379 restart
2.3 AOF 执行流程
AOF 持久化分为命令追加、文件写入与同步、文件重写三大阶段,每个阶段均为保障“性能”与“数据安全”的平衡设计。
2.3.1 阶段1:命令追加(append)
- 逻辑:Redis 执行写命令后,不直接写入磁盘,而是先将命令按“Redis 协议格式”(纯文本,如
*3\r\n$3\r\nset\r\n$2\r\nk1\r\n$1\r\n1\r\n
)追加到内存缓冲区aof_buf
。 - 目的:避免每一条写命令都触发磁盘 IO(磁盘 IO 速度远低于内存),减少对 Redis 性能的影响。
2.3.2 阶段2:文件写入与同步(write + sync)
aof_buf
中的命令需写入磁盘才能保障安全,Redis 通过“同步策略”控制写入频率,核心依赖操作系统的 write
和 fsync
函数:
write
函数:将数据写入操作系统内核缓冲区,不立即刷盘(由操作系统控制刷盘时机,通常 30 秒一次),性能高但数据不安全。fsync
函数:强制将内核缓冲区数据刷入磁盘,数据安全但性能低。
Redis 提供 3 种同步策略,配置在 /etc/redis/6379.conf
的 appendfsync
参数中:
同步策略 | 执行逻辑 | 数据安全性 | 性能 | 适用场景 |
---|---|---|---|---|
always | 命令追加到 aof_buf 后,立即调用 fsync 刷盘,fsync 完成后返回 | 最高(零丢失) | 最低(IO 瓶颈) | 金融核心数据(如交易记录) |
everysec | 命令追加到 aof_buf 后,先调用 write 写入内核缓冲区,由专门线程每秒 fsync 一次 | 较高(最多丢1秒) | 均衡(推荐) | 绝大多数生产场景 |
no | 仅调用 write 写入内核缓冲区,刷盘由操作系统控制(默认 30 秒) | 最低(丢30秒) | 最高 | 非核心数据(如临时缓存) |
注意:
everysec
是默认且推荐的策略——兼顾“数据安全”(最多丢 1 秒)和“性能”(每秒仅一次fsync
),避免always
的 IO 瓶颈和no
的高丢失风险。
2.3.3 阶段3:文件重写(rewrite)
AOF 文件会随写命令累积而“膨胀”(如反复执行 set k1 1
/set k1 2
,AOF 会记录两条命令),导致文件过大、恢复速度慢,文件重写的作用是“压缩 AOF 文件”,核心是“保留最终数据状态,删除无效命令”。
(1)重写原理
重写不读取旧 AOF 文件,而是直接读取 Redis 内存中的当前数据,生成“最小化命令集”写入新 AOF 文件,压缩逻辑包括:
- 删除过期数据对应的命令(如已过期的
set k1 1
); - 合并无效命令(如
set k1 1
/set k1 2
合并为set k1 2
); - 批量合并命令(如
sadd set1 a
/sadd set1 b
合并为sadd set1 a b
)。
(2)触发方式
重写分为手动触发和自动触发:
- 手动触发:执行
bgrewriteaof
命令(与bgsave
类似,fork
子进程处理,主进程不阻塞):127.0.0.1:6379> bgrewriteaof Background append only file rewrite started
- 自动触发:需同时满足两个配置条件(在
/etc/redis/6379.conf
中):# 729行:当前AOF文件大小是上次重写后大小的2倍(百分比可调整) auto-aof-rewrite-percentage 100 # 当前AOF文件大小≥64MB(避免小文件频繁重写) auto-aof-rewrite-min-size 64mb
(3)重写流程
重写过程需保障“数据不丢失”,核心依赖 aof_rewrite_buf
缓冲区,步骤如下:
- 主进程判断是否存在
bgsave
/bgrewriteaof
子进程,若存在则返回;若存在bgsave
,则等待其完成后再执行。 - 主进程
fork
子进程(阻塞期),子进程负责生成新 AOF 文件。 - 主进程恢复处理命令:
- 写命令继续追加到
aof_buf
(保障原有 AOF 机制正常); - 同时追加到
aof_rewrite_buf
(避免重写期间的命令丢失)。
- 写命令继续追加到
- 子进程读取内存数据,生成新 AOF 文件。
- 子进程完成后发送信号给主进程,主进程将
aof_rewrite_buf
中的命令追加到新 AOF 文件(确保新文件与当前内存数据一致)。 - 新 AOF 文件原子替换旧文件,重写完成。
2.4 启动时加载
AOF 加载优先级高于 RDB,流程与 RDB 类似,但对文件异常的处理更灵活:
- 加载顺序:Redis 启动时,若 AOF 开启且
appendonly.aof
存在,优先加载 AOF 文件;仅当 AOF 关闭或文件不存在时,才加载 RDB 文件。 - 异常处理:
- 若 AOF 文件完全损坏(如磁盘错误),Redis 启动失败,需用
redis-check-aof
工具修复(如redis-check-aof --fix appendonly.aof
); - 若 AOF 文件尾部不完整(如宕机导致),且
aof-load-truncated=yes
(默认开启),Redis 会忽略尾部损坏部分,启动成功并打印警告日志。
- 若 AOF 文件完全损坏(如磁盘错误),Redis 启动失败,需用
2.5 优缺点分析
优点 | 缺点 |
---|---|
实时性好:everysec 策略最多丢失 1 秒数据,远优于 RDB | AOF 文件为纯文本,体积远大于 RDB(如 1GB 内存数据,AOF 可能达 10GB) |
兼容性强:纯文本命令格式,跨 Redis 版本兼容 | 数据恢复速度慢(需重放所有命令,而非直接加载二进制) |
命令可追溯:AOF 文件可直接查看历史写命令,便于问题排查 | IO 压力大:everysec 策略每秒 fsync ,磁盘 IO 频率高于 RDB |
重写机制保障文件体积可控 | 重写时 fork 子进程会阻塞主进程,且消耗 CPU/内存 |
3. RDB 与 AOF 全方位对比
对比维度 | RDB 持久化 | AOF 持久化 |
---|---|---|
数据安全性 | 低(快照间隔内丢失数据,如 60 秒) | 高(everysec 最多丢 1 秒,always 零丢失) |
文件体积 | 小(二进制压缩) | 大(纯文本命令,需重写压缩) |
恢复速度 | 快(直接加载二进制文件) | 慢(重放所有命令) |
性能影响 | 小(仅 fork 时阻塞,子进程写盘) | 中(everysec 每秒 fsync ,IO 压力大) |
兼容性 | 差(版本不兼容) | 好(纯文本命令跨版本支持) |
适用场景 | 全量备份、非核心数据、主从全量复制 | 核心数据、需低丢失风险、命令追溯场景 |
4. 实际应用选择建议
持久化方案的选择需结合业务对“数据安全性”“性能”“维护成本”的需求,核心建议如下:
-
仅用 RDB:
场景:非核心缓存数据(如商品详情临时缓存)、需频繁全量备份(如每天凌晨备份);
优势:备份文件小,恢复快,对性能影响低。 -
仅用 AOF:
场景:核心业务数据(如用户余额、订单状态)、需低数据丢失风险;
配置:appendfsync everysec
+ 自动重写(auto-aof-rewrite-percentage 100
+64mb
),兼顾安全与性能。 -
RDB + AOF 结合(推荐生产核心场景):
优势:AOF 保障数据低丢失(秒级),RDB 提供快速全量恢复能力(避免 AOF 重放耗时);
逻辑:日常依赖 AOF 实时持久化,定期(如每天)用bgsave
生成 RDB 做全量备份,宕机时优先加载 AOF 恢复最新数据,若 AOF 损坏则用 RDB 兜底。
通过合理选择持久化方案,可在“数据安全”与“Redis 性能”之间找到最佳平衡,避免因持久化配置不当导致的数据丢失或性能瓶颈。
总结
Redis 作为高性能键值数据库,核心价值在于“快”与“灵活”——纯内存操作保障极致性能,丰富的数据结构与高可用方案支持复杂业务场景。实际应用中需注意:
- 定位清晰:Redis 是“缓存+轻量存储”工具,不替代关系型数据库(如 MySQL 用于持久化存储核心业务数据,Redis 用于缓存高频访问数据)。
- 数据安全:生产环境优先开启 AOF(everysec 策略),结合 RDB 全量备份,避免数据丢失。
- 高可用选型:
- 中小规模场景:主从复制+哨兵(足够应对大部分业务)
- 大规模/高并发场景:Cluster 集群(支持分布式存储与写负载均衡)
- 性能优化:定期监控内存碎片率,合理设置键过期时间与内存淘汰策略,避免内存溢出与性能下降。
通过本文的学习,可掌握 Redis 从安装部署到生产优化的全流程,为实际业务中的缓存设计、高可用保障提供技术支撑。