Redis

一、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
  • 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 个槽位);
  • 作用:解决单节点内存限制,支持水平扩展;
  • 部署步骤
    1. 启动多个 Redis 节点,开启 cluster-enabled yes;
    1. 执行 redis-cli --cluster create 节点1:6379 节点2:6379 ... --cluster-replicas 1;
    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 性能优化技巧
  1. 避免大键 / 热键
    • 大键拆分(如百万元素的 Hash 拆分为 100 个小 Hash);
    • 热键处理:本地缓存(Caffeine)+ 热键分片(hot:key:1~hot:key:N);
  1. 命令优化
    • 用 HSCAN/SCAN/ZSCAN 替代 HGETALL/SMEMBERS 等全量命令;
    • 批量操作(MSET/MGET)减少网络往返;
  1. 持久化优化
    • 避免在高峰期触发 RDB 快照(调整 save 配置);
    • AOF 重写触发阈值调整(auto-aof-rewrite-percentage 100);
  1. 集群优化
    • 槽位均衡分配,避免单节点压力过大;
    • 开启集群 slot 统计(cluster-slot-stats-enabled yes,Redis 8.6+)。
6.2 运维监控工具
  1. 官方工具
    • redis-cli --bigkeys:检测大键;
    • redis-cli info:查看服务状态(内存、CPU、连接数);
    • redis-cli HOTKEYS:实时检测热键(Redis 8.6+);
  1. 可视化工具
    • Redis Insight(官方推荐,支持集群管理、数据可视化);
    • Grafana + Prometheus:监控指标(QPS、响应时间、内存使用率);
  1. 核心监控指标
    • 内存:used_memory、used_memory_rss;
    • 性能:redis_version、instantaneous_ops_per_sec(QPS);
    • 高可用:role(主 / 从)、connected_slaves(从节点数)。
6.3 常见问题排查
  1. 连接数耗尽
    • 原因:maxclients 配置过小,或应用未释放连接;
    • 解决:增大 maxclients(如 10000),检查应用连接池配置;
  1. CPU 利用率过高
    • 原因:大键操作、热键过多、持久化线程占用;
    • 解决:优化大键 / 热键,调整持久化策略;
  1. 主从同步延迟
    • 原因:网络波动、从节点压力过大;
    • 解决:优化网络,增加从节点,避免从节点读压力过大。

七、Redis 版本升级与未来展望

7.1 版本升级注意事项
  • 低版本 → 8.6.0 兼容要点:
    • Lua 脚本不再持久化(需迁移为 Function 函数库);
    • Ziplist 编码替换为 Listpack(无需手动处理,自动兼容);
  • 升级步骤:先升级从节点 → 切换主节点 → 升级原主节点。
7.2 未来发展趋势
  • 性能持续优化:多线程模型深化、内存结构优化;
  • 功能拓展:时间序列数据支持增强、AI 集成(如向量搜索);
  • 易用性提升:集群管理简化、自动化运维工具完善;
  • 安全性强化:ACL 权限细化、加密机制升级。
相关推荐
Zzj_tju2 小时前
Java 从入门到精通(九):集合框架入门,List、Set、Map 到底该怎么选?
java·开发语言·list
东离与糖宝2 小时前
Java 26惰性常量+HTTP/3:AI微服务启动提速5倍实战
java·人工智能
爱码少年2 小时前
Springboot 工程中快速判断web应用服务器类型
java·spring boot
敲代码的嘎仔2 小时前
Java后端开发——多线程面试题
java·开发语言·面试·多线程·八股·threadlocal·
sonnet-10292 小时前
交换排序算法
java·c语言·开发语言·数据结构·笔记·算法·排序算法
NGC_66112 小时前
深度解析 ConcurrentHashMap 1.8:put 与 get 核心流程全解
java·开发语言
杭州杭州杭州2 小时前
J2EE实验
java·java-ee
福运常在2 小时前
股票数据API如何获取(20)炸板股池数据
java·python·maven
2501_941982052 小时前
企微私域:实现企业通讯工具外部群消息的自动化主动推送
java·前端·javascript