Redis 常见任务上手
本页是任务式教程,不是连续项目。先按要解决的问题选择章节,再打开 redis-cli 执行示例。命令后的 # 注释表示预期返回;实际返回取决于已有数据。
开始前启动一个开发实例,参见在本机安装 Redis。示例命令会创建测试 Key,生产环境不要直接执行。
1. String:计数器
String 最典型的用法是原子计数。单线程保证 INCR 原子,100 个请求同时点进来也不会算错。
bash
# 页面访问计数
INCR page:home:views # (integer) 1
GET page:home:views # "1"
# 每日计数(用日期做 key)
INCR counter:2026-08-31:login # (integer) 1
EXPIRE counter:2026-08-31:login 86400
# 文章阅读量
SET article:1001:views 0 # OK
INCR article:1001:views # (integer) 1
INCRBY article:1001:views 10 # (integer) 11 一次加 10
GET article:1001:views # "11"2. String:缓存层
读多写少的数据可以使用 Cache Aside 模式。下面只展示 Redis 端的读写动作,不代表完整的缓存一致性方案。
bash
# 查询时先查缓存
GET user:1001
# 缓存未命中,查数据库后写入
SET user:1001 '{"id":1001,"name":"alice"}' EX 3600
# 更新时删除缓存
DEL user:10013. Hash:购物车
购物车是典型的「一个对象多个字段」,用 Hash 存,商品 ID 做 field、数量做 value。
bash
HSET cart:u001 p001 2 p002 1 # (integer) 2 加入两件商品
HINCRBY cart:u001 p001 1 # (integer) 3 p001 数量 +1
HGET cart:u001 p001 # "3"
HGETALL cart:u001 # 1) "p001" 2) "3" 3) "p002" 4) "1"
HDEL cart:u001 p002 # (integer) 1 删除商品4. List:消息队列
List 两端操作配合 BLPOP,可以演示最简单的任务分发。
两个终端配合:终端 A 作为消费者阻塞等待,终端 B 作为生产者入队。
bash
# 终端 A(消费者):阻塞等待,最多等 30 秒
BLPOP task:queue 30bash
# 终端 B(生产者):入队一条任务
RPUSH task:queue "send_email:user123" # (integer) 1终端 A 立即弹出结果:
bash
1) "task:queue"
2) "send_email:user123"
(12.03s)
BLPOP的妙处:队列为空时消费者不会空转轮询,而是挂起等待,省 CPU。
这个模式没有确认、重试和消费进度,不能直接承担不可丢失的任务。需要可靠消费时,参见消息场景。
5. Set:共同好友
Set 自动去重 + 集合运算,算共同好友、做推荐一条命令搞定。
bash
SADD friend:u1 u2 u3 u4 # (integer) 3
SADD friend:u2 u1 u3 u5 # (integer) 3
SINTER friend:u1 friend:u2 # 1) "u3" 共同好友
SDIFF friend:u1 friend:u2 # 1) "u4" 我关注了但对方没有(可做推荐)
SISMEMBER friend:u1 u2 # (integer) 1 判断是否已关注6. ZSet:排行榜
ZSet 按 score 自动排序,ZADD 写分、ZINCRBY 改分、ZREVRANGE 取 TopN,一条命令搞定排序 + 范围查询。
bash
# 添加分数
ZADD leaderboard 100 "alice" 85 "bob" 92 "charlie" # (integer) 3
# Top 3(降序)
ZREVRANGE leaderboard 0 2 WITHSCORES
# 1) "alice" 2) "100"
# 3) "charlie" 4) "92"
# 5) "bob" 6) "85"
# 查询排名
ZREVRANK leaderboard "alice" # (integer) 0 排名从 0 起
# 加分后名次上升
ZINCRBY leaderboard 50 "alice" # (integer) 150
ZRANK leaderboard "alice" # (integer) 0 仍是第 1 名7. 分布式锁
下面的命令演示带过期时间和归属校验的锁。锁不能替代业务幂等和数据库事务,分布式锁的完整边界见分布式锁。
bash
# 加锁(NX=不存在才设置,EX=过期时间)
SET lock:order:1001 "request-8f31" NX EX 30
# 解锁(Lua 脚本保证原子性)
EVAL "
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
" 1 lock:order:1001 "request-8f31"锁必须带过期时间(防死锁),解锁必须校验归属(防误删别人的锁)。