Redis 入门实战:5 个数据结构写出常用的缓存场景
数据库查一次要几十毫秒,高频读起来扛不住,Redis 就是用来挡在数据库前面的内存缓存。它快的原因很简单:数据全在内存里,单线程模型又省掉了锁竞争。下面用 5 个数据结构,对应 5 个最常见的缓存场景。
1. String:缓存单条数据
最常用的结构就是字符串,一条命令存、一条命令取:
SET user:1001 "{\"name\":\"小明\",\"age\":20}" EX 3600
GET user:1001
EX 3600 是过期时间,3600 秒后自动失效,避免脏数据一直留着。计数场景也用它,INCR page:view:20261107 一天下来就是当天的浏览量,原子操作不用担心并发多算。
2. Hash:缓存一个对象
用户信息有十几个字段时,拆成十几个 String 太散,用 Hash 一次存一个对象:
HSET user:1001 name 小明 age 20 city 北京
HGETALL user:1001
HGET user:1001 city
只改一个字段用 HSET user:1001 age 21,不用把整个对象读出来再写回去。对象字段不多、读改频繁时,Hash 比 String 更省事。
3. List:消息队列和最新列表
List 两头都能进出,天然适合做队列。生产者往右边推,消费者从左边取:
RPUSH task:queue "order-1001"
LPOP task:queue
最新动态列表也一样:LPUSH feed:user:1001 "新文章发布",再用 LRANGE feed:user:1001 0 9 取最新的 10 条,配合 LTRIM 只保留前 100 条,列表永远不会无限变长。
4. Set:去重和交集
Set 自动去重,适合点赞、签到这类“同一个用户只能算一次”的场景:
SADD article:1001:liked user:1001 user:1002
SISMEMBER article:1001:liked user:1001
SCARD article:1001:liked
SISMEMBER 判断某人有没有点过赞,SCARD 直接给点赞总数。两个 Set 求交集 SINTER 还能算共同好友、共同标签,数据库里写起来麻烦的查询,一条命令就有了。
5. ZSet:排行榜
带分数的有序集合是排行榜的标配,分数就是排序依据:
ZADD rank:score 98 user:1001 95 user:1002
ZREVRANGE rank:score 0 9 WITHSCORES
ZRANK rank:score user:1001
ZREVRANGE 取前 10 名,ZRANK 查某个人的名次,分数一变名次自动重排。热搜榜、积分榜、阅读量榜都是这个套路,数据量再大也只要一次查询。
缓存使用时最容易踩的三个坑
第一,缓存穿透:查一个不存在的 key,请求每次都打到数据库。办法是查不到也缓存一个空值,过期时间设短一点,或者在入口先做布隆过滤。
第二,缓存雪崩:大量 key 同时过期,数据库瞬间被打满。给过期时间加一个随机值错开,别让所有 key 在同一秒失效。
第三,缓存击穿:某个热点 key 过期那一刻,大量请求同时回源。热点 key 可以设置不过期、后台定时刷新,或者只放一个请求去回源、其他请求等结果。
小结
String 存单值和计数,Hash 存对象,List 做队列和最新列表,Set 做去重和交集,ZSet 做排行榜。先想清楚场景要什么操作,再选结构,Redis 用起来就不会乱。本地装一个 Redis,用 redis-cli 把上面 5 组命令敲一遍,比看十篇概念文章记得牢。
- 点赞
- 收藏
- 关注作者
评论(0)