一、Redis 是什么?------ 高性能内存数据库的核心定位
1.1 定义与核心特性
Redis(Remote Dictionary Server)是一款开源的高性能键值对内存数据库,以 "快" 为核心优势,支持多种数据结构,兼具持久化、高可用和分布式能力。其核心特性包括:
- 内存存储:数据优先存储于内存,读写速度达 10 万 + QPS,远超传统磁盘数据库;
- 多数据结构:支持字符串(String)、哈希(Hash)、列表(List)等 8 种核心数据结构,适配复杂业务场景;
- 单线程模型:主线程串行处理命令,避免线程切换开销,配合 I/O 多路复用提升并发能力;
- 持久化机制:支持 RDB、AOF 及混合持久化,兼顾性能与数据安全性;
- 高可用架构:提供主从复制、哨兵模式、Redis Cluster 集群方案,保障服务稳定性;
- 跨平台兼容:支持 Linux、Windows、macOS,可通过 Docker 快速部署。
1.2 发展历程与最新版本
Redis 自 2009 年发布以来持续迭代,各版本关键特性如下:
- 3.0(2015):推出官方分布式方案 Redis Cluster;
- 4.0(2017):支持模块系统、LFU 淘汰算法、异步删除大键(UNLINK);
- 5.0(2018):新增 Stream 数据类型、集群管理器移植为 C 代码;
- 6.0(2020):引入多线程 I/O、ACL 权限控制、SSL 支持;
- 7.0(2022):新增 Function 函数库、Multi-Part AOF、Sharded-Pub/Sub;
- 8.6.0(2026):性能暴涨 30%+、内存占用下降 20%、新增热键检测(HOTKEYS 命令)、基于修改时间的逐出策略(volatile-lrm/allkeys-lrm)。
当前生产环境推荐使用 Redis 8.6.0(稳定版),其内存优化和热键检测功能大幅提升运维效率。
1.3 典型应用场景
- 缓存层:作为数据库前置缓存,降低 DB 压力(如电商商品详情缓存);
- 分布式锁:基于 SETNX + EXPIRE 实现分布式环境下的资源互斥;
- 限流熔断:用 Redis + Lua 脚本实现接口 QPS 限流(如秒杀活动限流);
- 消息队列:通过 List/Stream 实现轻量级消息队列(替代 RabbitMQ 简化架构);
- 排行榜:利用 Sorted Set 的排序特性实现实时排行榜(如游戏积分排名);
- 地理位置服务:GEO 数据结构支持附近的人、商家定位等场景。
二、Redis 安装与环境配置
2.1 多环境安装指南
(1)Linux 系统(Ubuntu/Debian)
# 1. 安装依赖
sudo apt update && sudo apt install -y gcc make
# 2. 下载最新稳定版(8.6.0)
wget https://download.redis.io/releases/redis-8.6.0.tar.gz
tar -zxvf redis-8.6.0.tar.gz && cd redis-8.6.0
# 3. 编译安装
make && sudo make install
# 4. 启动服务
redis-server /etc/redis/redis.conf # 配置文件需手动复制到/etc/redis
(2)Docker 快速部署
# 拉取官方镜像
docker pull redis:8.6.0
# 启动容器(映射端口+挂载配置+持久化数据)
docker run -d \
--name redis-8.6 \
-p 6379:6379 \
-v /data/redis/conf:/etc/redis \
-v /data/redis/data:/data \
redis:8.6.0 \
redis-server /etc/redis/redis.conf
(3)Windows/macOS
- Windows:通过 Redis 官方 Windows 版 或 WSL2 安装;
- macOS:brew install redis,启动命令 brew services start redis。
2.2 核心配置文件详解(redis.conf)
生产环境需重点配置以下参数:
# 1. 基础配置
bind 0.0.0.0 # 允许所有IP访问(生产环境限制指定IP)
port 6379 # 端口号
requirepass 123456 # 访问密码(必填,避免未授权访问)
daemonize yes # 后台运行
pidfile /var/run/redis.pid # PID文件路径
# 2. 内存限制
maxmemory 4gb # 最大使用内存(建议为物理内存的50%-70%)
maxmemory-policy allkeys-lfu # 内存满时的淘汰策略(8.6+支持allkeys-lrm)
# 3. 持久化配置
save 900 1 # 900秒内修改1次触发RDB快照
save 300 10 # 300秒内修改10次触发RDB
appendonly yes # 开启AOF持久化
appendfsync everysec # 每秒同步AOF文件(性能与安全平衡)
aof-use-rdb-preamble yes # 开启混合持久化(Redis 4.0+)
# 4. 高可用配置
replicaof 192.168.1.100 6379 # 从节点指向主节点(主从复制)
cluster-enabled yes # 开启集群模式(Redis 3.0+)
cluster-node-timeout 15000 # 集群节点超时时间(15秒)
2.3 客户端连接与测试
# 本地连接
redis-cli -h 127.0.0.1 -p 6379 -a 123456
# 测试命令
127.0.0.1:6379> SET test_key "hello redis"
OK
127.0.0.1:6379> GET test_key
"hello redis"
127.0.0.1:6379> INFO # 查看服务状态
三、Redis 核心数据结构与命令实战
3.1 字符串(String)------ 最基础的键值类型
用途:存储字符串、数字、二进制数据(如图片 Base64),支持原子操作。
核心命令:
SET key value [EX seconds] # 设置值(可选过期时间)
GET key # 获取值
INCR key # 数字自增1(适用于计数器)
DECR key # 数字自减1
APPEND key "suffix" # 追加字符串
STRLEN key # 获取字符串长度
实战场景:用户登录状态缓存(SET user:token:1001 "xxx" EX 3600)、商品库存计数(INCR product:stock:10086)。
3.2 哈希(Hash)------ 适合存储对象
用途:存储结构化数据(如用户信息、商品详情),支持字段级操作。
核心命令:
HSET user:1001 name "张三" age 25 # 设置多个字段
HGET user:1001 name # 获取单个字段
HGETALL user:1001 # 获取所有字段(大键慎用)
HSCAN user:1001 0 COUNT 10 # 分段获取(替代HGETALL)
HDEL user:1001 age # 删除字段
优势:无需序列化整个对象,修改单个字段更高效。
3.3 列表(List)------ 有序可重复的元素集合
用途:消息队列、最新消息列表、栈 / 队列实现。
核心命令:
LPUSH list:msg "msg1" # 左侧插入(栈:LPUSH+LPOP;队列:LPUSH+RPOP)
RPUSH list:msg "msg2" # 右侧插入
LRANGE list:msg 0 -1 # 获取所有元素(大列表慎用)
LTRIM list:msg 0 99 # 保留前100个元素(避免列表过大)
BLPOP list:msg 10 # 阻塞式左侧弹出(10秒超时,适用于消息队列)
实战场景:用户消息盒(LPUSH msg:user:1001 "您有新消息")、秒杀队列(BLPOP seckill:queue 0)。
3.4 集合(Set)------ 无序不可重复的元素集合
用途:去重、交集 / 并集 / 差集计算(如好友关系)。
核心命令:
SADD set:user:1001 2001 2002 2003 # 添加好友ID
SMEMBERS set:user:1001 # 获取所有好友(大集合慎用)
SISMEMBER set:user:1001 2001 # 判断是否为好友
SINTER set:user:1001 set:user:2001 # 求交集(共同好友)
SUNION set:user:1001 set:user:2001 # 求并集
3.5 有序集合(Sorted Set)------ 带分数的排序集合
用途:实时排行榜、优先级队列(分数作为优先级)。
核心命令:
ZADD rank:game 95 user:1001 88 user:1002 # 添加用户分数
ZRANGE rank:game 0 9 WITHSCORES # 获取前10名(升序)
ZREVRANGE rank:game 0 9 WITHSCORES # 降序排列(排行榜常用)
ZINCRBY rank:game 5 user:1001 # 分数增加5分
ZSCORE rank:game user:1001 # 获取用户分数
实战场景:游戏积分排行榜(ZREVRANGE rank:game 0 9)、任务优先级队列(分数越高越先执行)。
3.6 其他数据结构
- GEO:存储地理位置坐标,支持距离计算(GEOADD location:shop 116.40 39.90 "故宫"、GEODIST location:shop "故宫" "颐和园" km);
- Stream:Redis 5.0+ 新增,支持消息持久化、消费组模式(替代 List 实现更可靠的消息队列);
- HyperLogLog:基数统计(如 UV 统计),占用内存极小(12KB 可统计 2^64 数据)。
四、Redis 高级特性:持久化、缓存策略与高可用
4.1 持久化机制 ------ 避免内存数据丢失
Redis 提供两种持久化方式,可单独使用或混合配置:
|-------|-------------------|---------------------|---------------------|
| 方式 | 原理 | 优点 | 缺点 |
| RDB | 定时生成内存快照(.rdb 文件) | 恢复速度快、对性能影响小 | 可能丢失最近数据(如崩溃前未触发快照) |
| AOF | 记录所有写命令(.aof 文件) | 数据完整性高(每秒 / 每次命令同步) | 恢复速度慢、文件体积大 |
| 混合持久化 | RDB 快照 + AOF 增量命令 | 兼顾恢复速度与数据安全性 | Redis 4.0+ 支持,需手动开启 |
生产配置建议:开启混合持久化(aof-use-rdb-preamble yes),AOF 同步策略设为 everysec(每秒同步),避免 always(每次命令同步)导致性能下降。
4.2 缓存策略 ------ 解决缓存常见问题
(1)缓存过期淘汰
Redis 过期键删除采用「被动删除 + 主动定期删除」策略:
- 被动删除:访问键时才检查是否过期;
- 主动删除:每 10ms 随机抽查部分过期键。
优化建议:避免大量键同一时间过期(如给过期时间加随机偏移量 EX 3600 + random(0, 600)),防止集中删除阻塞线程。
(2)缓存三大问题解决方案
|------|-----------------|----------------------------------------------|
| 问题 | 场景 | 解决方案 |
| 缓存穿透 | 访问不存在的键,请求直达 DB | 1. 空值缓存(SET key "" EX 300);2. 布隆过滤器拦截无效键 |
| 缓存击穿 | 热点键过期,大量请求穿透 DB | 1. 热点键永不过期;2. 互斥锁(SETNX)防止并发回写 DB |
| 缓存雪崩 | 大量缓存集中过期,DB 被压垮 | 1. 过期时间加随机偏移;2. 多级缓存(本地缓存 + Redis);3. 服务限流降级 |
代码示例(缓存穿透 - 空值缓存):
String value = redisTemplate.opsForValue().get(key);
if (value == null) {
// 查数据库
String dbValue = db.query(key);
if (dbValue == null) {
// 缓存空值,设置短过期时间
redisTemplate.opsForValue().set(key, "", 5, TimeUnit.MINUTES);
} else {
redisTemplate.opsForValue().set(key, dbValue, 3600, TimeUnit.SECONDS);
}
return dbValue;
}
return value;
4.3 高可用架构部署
(1)主从复制
- 架构:1 主 N 从(主写从读),从节点通过复制同步主节点数据;
- 作用:分担读压力、主节点故障时从节点可晋升为主;
- 配置:从节点配置 replicaof 主节点IP 端口,主节点需开启密码认证。
(2)哨兵模式(Sentinel)
- 架构:3 个哨兵节点 + 主从复制集群;
- 作用:自动监控主从节点状态,主节点故障时自动切换从节点为新主;
- 核心功能:故障检测、自动故障转移、配置中心。
(3)Redis Cluster 集群
- 架构:3 主 3 从(最小配置),数据分片存储(共 16384 个槽位);
- 作用:解决单节点内存限制,支持水平扩展;
- 部署步骤:
-
- 启动多个 Redis 节点,开启 cluster-enabled yes;
-
- 执行 redis-cli --cluster create 节点1:6379 节点2:6379 ... --cluster-replicas 1;
-
- 集群自动分配槽位,主从节点配对。
五、Redis 实战:分布式锁与限流实现
5.1 分布式锁(基于 Redis + Lua)
核心需求:分布式环境下保证同一资源同一时间只有一个线程操作。
实现方案:
-- 加锁脚本(保证原子性)
if redis.call('SETNX', KEYS[1], ARGV[1]) == 1 then
return redis.call('EXPIRE', KEYS[1], ARGV[2])
else
return 0
end
-- 解锁脚本(防止误删其他线程的锁)
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
else
return 0
end
Java 调用示例:
String lockKey = "lock:product:10086";
String lockValue = UUID.randomUUID().toString();
int expireTime = 30; // 锁过期时间(秒)
// 加锁
Boolean locked = redisTemplate.execute(new DefaultRedisScriptlockScript, Boolean.class),
Collections.singletonList(lockKey), lockValue, String.valueOf(expireTime));
if (locked) {
try {
// 业务逻辑(如扣减库存)
} finally {
// 解锁
redisTemplate.execute(new DefaultRedisScript<>(unlockScript, Long.class),
Collections.singletonList(lockKey), lockValue);
}
}
5.2 接口限流(基于 Redis + Lua)
需求:限制接口每秒最大 QPS(如 100)。
实现方案(滑动窗口算法):
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local now = tonumber(ARGV[2])
local window = tonumber(ARGV[3]) -- 窗口大小(秒)
-- 移除窗口外的请求
redis.call('ZREMRANGEBYSCORE', key, 0, now - window * 1000)
-- 获取当前请求数
local count = redis.call('ZCARD', key)
if count then
-- 添加当前请求时间戳
redis.call('ZADD', key, now, now .. ':' .. math.random())
-- 设置窗口过期时间
redis.call('EXPIRE', key, window)
return 1 -- 允许访问
end
return 0 -- 拒绝访问
六、Redis 性能优化与运维监控
6.1 性能优化技巧
- 避免大键 / 热键:
-
- 大键拆分(如百万元素的 Hash 拆分为 100 个小 Hash);
-
- 热键处理:本地缓存(Caffeine)+ 热键分片(hot:key:1~hot:key:N);
- 命令优化:
-
- 用 HSCAN/SCAN/ZSCAN 替代 HGETALL/SMEMBERS 等全量命令;
-
- 批量操作(MSET/MGET)减少网络往返;
- 持久化优化:
-
- 避免在高峰期触发 RDB 快照(调整 save 配置);
-
- AOF 重写触发阈值调整(auto-aof-rewrite-percentage 100);
- 集群优化:
-
- 槽位均衡分配,避免单节点压力过大;
-
- 开启集群 slot 统计(cluster-slot-stats-enabled yes,Redis 8.6+)。
6.2 运维监控工具
- 官方工具:
-
- redis-cli --bigkeys:检测大键;
-
- redis-cli info:查看服务状态(内存、CPU、连接数);
-
- redis-cli HOTKEYS:实时检测热键(Redis 8.6+);
- 可视化工具:
-
- Redis Insight(官方推荐,支持集群管理、数据可视化);
-
- Grafana + Prometheus:监控指标(QPS、响应时间、内存使用率);
- 核心监控指标:
-
- 内存:used_memory、used_memory_rss;
-
- 性能:redis_version、instantaneous_ops_per_sec(QPS);
-
- 高可用:role(主 / 从)、connected_slaves(从节点数)。
6.3 常见问题排查
- 连接数耗尽:
-
- 原因:maxclients 配置过小,或应用未释放连接;
-
- 解决:增大 maxclients(如 10000),检查应用连接池配置;
- CPU 利用率过高:
-
- 原因:大键操作、热键过多、持久化线程占用;
-
- 解决:优化大键 / 热键,调整持久化策略;
- 主从同步延迟:
-
- 原因:网络波动、从节点压力过大;
-
- 解决:优化网络,增加从节点,避免从节点读压力过大。
七、Redis 版本升级与未来展望
7.1 版本升级注意事项
- 低版本 → 8.6.0 兼容要点:
-
- Lua 脚本不再持久化(需迁移为 Function 函数库);
-
- Ziplist 编码替换为 Listpack(无需手动处理,自动兼容);
- 升级步骤:先升级从节点 → 切换主节点 → 升级原主节点。
7.2 未来发展趋势
- 性能持续优化:多线程模型深化、内存结构优化;
- 功能拓展:时间序列数据支持增强、AI 集成(如向量搜索);
- 易用性提升:集群管理简化、自动化运维工具完善;
- 安全性强化:ACL 权限细化、加密机制升级。