Redis 缓存入门:常用数据结构与典型应用场景

举报
yd_297220493 发表于 2026/11/05 00:31:33 2026/11/05
【摘要】 从 String、Hash、List、Set、ZSet 五种常用结构讲起,结合缓存读写策略与穿透、击穿、雪崩三个常见问题,给出一份可直接上手的新手缓存入门指南。

为什么需要缓存

很多系统变慢,并不是数据库本身不够快,而是同样的查询被反复执行:商品详情、用户信息、排行榜、配置信息,这些数据读得多、改得少,每次都去查库既浪费连接,也拉高了响应时间。缓存的思路很直接:把热点数据放在离应用更近、访问更快的地方,读请求先查缓存,命中就直接返回,只有未命中时才回源查库并回填。

Redis 是目前最常用的内存缓存之一。它把数据放在内存里,读写延迟很低,还支持丰富的数据结构,不只是一个简单的键值对仓库。理解它的常用结构,才能在不同场景里选对工具,而不是把所有问题都塞进字符串里。

String:最简单的万能结构

String 是最基础的结构,一个键对应一个值,值可以是文本、数字,也可以是序列化的对象。常见用法包括缓存单个对象、计数、分布式锁的辅助值,以及用过期时间控制短期数据。

例如:

SET user:1001 "{\"name\":\"zhangsan\",\"level\":3}" EX 3600
GET user:1001
INCR page:view:home

使用 String 时要注意两点:一是值不宜过大,过大的对象会占用内存、拖慢序列化;二是需要过期时间时一定要设置,否则缓存会长期堆积,变成事实上的永久存储。

Hash:把对象拆成字段

当一个对象有多个字段,而且经常只改其中一两个字段时,Hash 更合适。它把一个键映射为多个字段,读改都可以只针对单个字段,不用整存整取。

HSET user:1001 name zhangsan level 3 city shenzhen
HGET user:1001 level
HGETALL user:1001

用户信息、商品属性、配置分组都适合用 Hash。它的好处是节省往返次数,也减少了因为改一个字段而重写整个对象的开销。

List:有序的队列与时间线

List 是按插入顺序排列的元素集合,支持从两端 push 和 pop,天然适合做队列和时间线。消息队列可以用 LPUSH 加 BRPOP 实现简单的生产消费;最新动态可以用 LPUSH 写入,再用 LRANGE 取前若干条;任务待处理列表也可以用它暂存。

需要注意的是,List 适合顺序消费和有限长度的场景,不适合频繁按下标随机访问或按条件查找,大量元素的中部操作成本较高,长度也应当控制,避免无限增长。

Set:去重与关系判断

Set 是无序、不重复的集合,适合做去重和关系运算。签到用户集合、点赞用户集合、标签集合都可以用它表示。SADD 加入,SISMEMBER 判断是否存在,SINTER 求交集,SUNION 求并集,这些操作在内存中完成,速度很快。

例如,共同关注、共同标签、黑名单判断,都可以用集合运算直接得出结果,而不需要把数据拉回应用层再逐条比较。

ZSet:带分数的有序集合

ZSet 在 Set 的基础上给每个成员加了一个分数,按分数排序,适合排行榜、延迟任务和按优先级排序的场景。ZADD 写入带分数的成员,ZREVRANGE 取分数最高的前若干名,ZRANGEBYSCORE 可以按分数区间查询,ZSCORE 可以查单个成员的分数。

积分榜、热度榜、按时间排序的待办任务,都可以用 ZSet 实现。它的排序由 Redis 维护,应用层不需要再做全量排序,分页取榜单也很方便。

缓存策略:先读缓存,再回源

最常见的读策略是 Cache Aside:先查缓存,命中返回;未命中查数据库,查到后写回缓存并设置过期时间。写策略则要根据一致性要求选择:可以先更新数据库再删除缓存,让下一次读重新回填;也可以先删缓存再更新数据库,但要处理并发读导致的旧值回填。

无论选哪种,都要接受一个基本事实:缓存与数据库之间很难做到强一致。多数业务场景接受短暂不一致,关键是把不一致的窗口控制在可接受范围内,并且对金额、库存这类敏感数据做额外的校验和兜底。

三个常见坑:穿透、击穿与雪崩

缓存穿透是指请求的数据根本不存在,缓存查不到,数据库也查不到,请求每次都打到数据库。缓解办法包括对空结果也做短时间缓存、做参数校验,以及在入口层拦截明显非法请求。

缓存击穿是指某个热点键过期的一瞬间,大量并发请求同时回源。缓解办法包括给热点键加逻辑过期、互斥锁回源,或者提前预热,让过期不发生在高峰期。

缓存雪崩是指大量键在同一时间过期,或者缓存整体不可用,导致请求集中涌向数据库。缓解办法包括过期时间加随机抖动、多级缓存、限流降级,以及做好缓存服务的容量与监控。

什么时候不适合用缓存

缓存不是万能药。写多读少的数据、强一致要求很高的数据、数据量巨大但命中率很低的数据,都不适合一味缓存。缓存还会带来运维成本:内存容量、过期策略、持久化、主从与集群、监控告警,都需要有人维护。

上线缓存前,先回答三个问题:这份数据的读频率有多高?不一致能容忍多久?缓存挂了业务还能不能降级运行?回答清楚这三个问题,再选结构、定过期时间、做兜底,缓存才能真正提速而不是添乱。

上手检查清单

一是按场景选结构:单个对象用 String,对象字段用 Hash,队列用 List,去重用 Set,排行用 ZSet。二是所有缓存键都要有过期时间,并给批量过期加随机抖动。三是键名要有命名规范,例如业务前缀加冒号加标识,便于排查和批量管理。四是关键路径要有降级:缓存不可用时直接查库或返回默认值,不要让缓存故障变成全站故障。五是上线后看命中率、内存占用和慢查询,定期清理不再使用的键。

把这份清单做成习惯,Redis 就不再只是一个装数据的盒子,而是一套可预期、可维护的缓存层。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。