Redis 在实际项目中的典型应用场景,包含实现方案、核心命令和常见问题解决。
最常见的 Redis 应用场景,加速数据访问,减轻数据库压力。
在 Web 应用中,数据库查询往往是性能瓶颈。使用 Redis 缓存热点数据,可以显著提升响应速度,降低数据库负载。
| 命令 | 说明 | 示例 |
|---|---|---|
SET key value EX seconds |
设置缓存,带过期时间 | SET user:1001 {...} EX 3600 |
GET key |
获取缓存 | GET user:1001 |
MGET key1 key2 |
批量获取 | MGET user:1 user:2 user:3 |
DEL key |
删除缓存 | DEL user:1001 |
EXISTS key |
检查是否存在 | EXISTS user:1001 |
查询不存在的数据,缓存层和数据库层都没有,导致每次请求都打到数据库。
大量缓存同时过期,导致请求全部打到数据库。
热点 key 过期瞬间,大量请求涌入数据库。
分布式系统中的用户会话存储方案。
在分布式 Web 应用中,需要在多个服务器之间共享用户会话信息。Redis 是理想的 Session 存储方案。
| 命令 | 说明 | 示例 |
|---|---|---|
SETEX key seconds value |
设置 Session,带过期时间 | SETEX sess:abc123 1800 {...} |
EXPIRE key seconds |
续期 Session | EXPIRE sess:abc123 1800 |
HSET key field value |
更新 Session 字段 | HSET sess:abc123 last_activity "12:30" |
HGETALL key |
获取完整 Session | HGETALL sess:abc123 |
DEL key |
注销 Session | DEL sess:abc123 |
Redis 重启或故障导致 Session 数据丢失,用户需要重新登录。
Session ID 被窃取,攻击者冒充用户。
使用有序集合实现实时排行榜。
游戏积分排行、销售排行、热度排行等场景,需要实时排序和查询排名。
| 命令 | 说明 | 示例 |
|---|---|---|
ZADD key score member |
添加/更新分数 | ZADD leaderboard:game1 9500 user:1001 |
ZREVRANGE key start stop |
获取前 N 名(降序) | ZREVRANGE leaderboard:game1 0 9 |
ZREVRANK key member |
获取排名 | ZREVRANK leaderboard:game1 user:1001 |
ZSCORE key member |
获取分数 | ZSCORE leaderboard:game1 user:1001 |
ZINCRBY key increment member |
增加分数 | ZINCRBY leaderboard:game1 100 user:1001 |
ZCARD key |
获取总人数 | ZCARD leaderboard:game1 |
多个用户分数相同时,如何确定排名?
排行榜用户量巨大(百万级),查询性能下降。
在分布式系统中实现互斥访问。
分布式系统中,多个节点需要互斥访问共享资源,如防止重复下单、库存扣减等。
| 命令 | 说明 | 示例 |
|---|---|---|
SET key value NX EX seconds |
原子性加锁 | SET lock:order123 uuid NX EX 10 |
DEL key |
释放锁 | DEL lock:order123 |
GET key |
检查锁持有者 | GET lock:order123 |
EXPIRE key seconds |
续期锁 | EXPIRE lock:order123 10 |
客户端 A 持有锁,但业务执行时间超过锁超时,锁自动释放。客户端 B 获得锁后,A 执行完成误删 B 的锁。
客户端 A 在主节点加锁,主节点宕机,锁未同步到从节点。从节点提升为主节点后,客户端 B 可以加锁。
使用 Redis 实现轻量级消息队列。
异步任务处理、服务解耦、流量削峰等场景,可以使用 Redis 实现轻量级消息队列。
| 方案 | 数据结构 | 优点 | 缺点 |
|---|---|---|---|
| List | LPUSH/BRPOP | 简单、高性能 | 无 ACK、不可重放 |
| Pub/Sub | PUBLISH/SUBSCRIBE | 实时广播 | 消息不持久、无消费者组 |
| Stream | XADD/XREADGROUP | 持久化、ACK、消费者组 | Redis 5.0+ |
消费者处理消息时宕机,消息丢失。
网络问题导致 ACK 未送达,消息被重新投递。
API 限流、防刷、速率控制。
保护系统免受过载攻击,限制用户或 IP 的请求频率。
多个 Redis 节点数据不同步,导致限流失效。
使用 Hash 结构实现高效的购物车功能。
电商应用中,购物车需要支持添加商品、修改数量、删除商品、计算总价等操作,且需要快速响应。
| 命令 | 说明 | 示例 |
|---|---|---|
HSET key field value |
添加/更新商品 | HSET cart:1001 product:101 2 |
HGET key field |
获取商品数量 | HGET cart:1001 product:101 |
HGETALL key |
获取购物车全部商品 | HGETALL cart:1001 |
HINCRBY key field increment |
增加商品数量 | HINCRBY cart:1001 product:101 1 |
HDEL key field |
删除商品 | HDEL cart:1001 product:101 |
HLEN key |
获取商品种类数 | HLEN cart:1001 |
EXPIRE key seconds |
设置过期时间 | EXPIRE cart:1001 2592000 |
Redis 故障导致用户购物车数据丢失,影响用户体验。
多个用户同时购买,库存扣减不一致。
高性能计数器,用于点赞、浏览、下载等统计。
文章阅读量、视频播放量、点赞数、下载计数等场景,需要高并发写入和实时读取。
| 命令 | 说明 | 示例 |
|---|---|---|
INCR key |
自增 1 | INCR article:views:12345 |
INCRBY key increment |
自增指定值 | INCRBY article:views:12345 5 |
DECR key |
自减 1 | DECR article:likes:12345 |
HINCRBY key field increment |
Hash 字段自增 | HINCRBY article:stats:12345 views 1 |
GET key |
获取计数值 | GET article:views:12345 |
MGET key1 key2 |
批量获取 | MGET article:views:1 article:views:2 |
Redis 宕机导致计数丢失,与数据库不一致。
黑产批量请求刷高计数。
基于位置的搜索、附近的人、配送范围等。
外卖配送、打车服务、社交应用等需要基于地理位置进行查询和匹配的场景。
| 命令 | 说明 | 示例 |
|---|---|---|
GEOADD key lng lat member |
添加位置 | GEOADD geo:users 116.4 39.9 user:1 |
GEODIST key member1 member2 |
计算距离 | GEODIST geo:users user:1 user:2 km |
GEORADIUS key lng lat radius |
范围内搜索 | GEORADIUS geo:users 116.4 39.9 10 km |
GEORADIUSBYMEMBER key member radius |
查询某人附近的 | GEORADIUSBYMEMBER geo:users user:1 5 km |
GEOPOS key member |
获取位置坐标 | GEOPOS geo:users user:1 |
GEOHASH key member |
获取 GeoHash | GEOHASH geo:users user:1 |
GeoHash 精度有限,极近距离可能不够准确。
司机/用户位置频繁变化,大量写入操作。