惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
有赞技术团队
有赞技术团队
Simon Willison's Weblog
Simon Willison's Weblog
人人都是产品经理
人人都是产品经理
L
LINUX DO - 最新话题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
A
Arctic Wolf
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
小众软件
小众软件
Jina AI
Jina AI
The Cloudflare Blog
P
Palo Alto Networks Blog
AWS News Blog
AWS News Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
Know Your Adversary
Know Your Adversary
T
Threat Research - Cisco Blogs
L
Lohrmann on Cybersecurity
NISL@THU
NISL@THU
G
GRAHAM CLULEY
Project Zero
Project Zero
博客园_首页
博客园 - 三生石上(FineUI控件)
罗磊的独立博客
Spread Privacy
Spread Privacy
WordPress大学
WordPress大学
Hugging Face - Blog
Hugging Face - Blog
Latest news
Latest news
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
S
Securelist
V
Vulnerabilities – Threatpost
T
The Exploit Database - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
IT之家
IT之家
Google DeepMind News
Google DeepMind News
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Last Watchdog
The Last Watchdog
T
Tenable Blog
宝玉的分享
宝玉的分享
S
Secure Thoughts
P
Privacy & Cybersecurity Law Blog
量子位
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Security Archives - TechRepublic
Security Archives - TechRepublic

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解 【002】HTTPS 粗解:证书、TLS 握手与对后端配置的影响 Hermes Agent 一周暴涨五万 Star,但我劝你别急着追 明明连接的是Redis的DB0,为什么能查到DB3的数据? 【从0到1构建一个ClaudeAgent】协作-Agent团队 熟悉电子元器件之后,电子小白下一步该怎么走? MAF快速入门(23)通过C#类定义Skills .NET 高级开发 | 手写一个对象映射框架 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 mysqldump 参数拾遗:在遗忘与铭记之间 C# .NET 周刊|2026年3月5期 Claude code入门 - 陈彦斌 一文学习入门 ThingsBoard 开源物联网平台 GitHub 热门项目 | 2026年04月16日 如何为GIT设置全局勾子,为每次提交追加信息 Number.isFinite和isFinite与isNaN()和Number.isNaN的区别 PortSwigger SQL注入LAB2 推荐一个测试人必备的Skills,从功能到性能全搞定(附详细实操和安装下载方式) 筑基期:掌握Odoo基础核心知识点02(Odoo XML 开发方式详解) GLM模型这么火,咱们用vllm也咧一个呗! 深入理解 AbortController:从底层原理到跨语言设计哲学 字符串学习笔记 多租户系统框架的基础模块设计和分析设计 Apache SeaTunnel Zeta 为什么能做到“又快又稳”? AI开发-python-LangGraph框架(3-26-LangGraph基本概念及第一个简单样例) Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 ElasticSearch7.X版本配置密码 用Manim实现动态交点计算--从一个动点问题说起 团结引擎+Addressable+Instant Game打包抖音小游戏 function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析 bubseek —— 让 Agent 的足迹,变成团队的洞察 通过 C# 读取并导出 PDF 书签 如何用 GitHub Actions 实现 Steam 自动化发布 【从0到1构建一个ClaudeAgent】并发-后台任务 .NET 高级开发 | 定制 ASP.NET Core 框架 电子小白:什么是运算放大器(运放) zero2Agent:面向大厂面试的 Agent 工程教程,从概念到生产的完整学习路线 堆上的ORW HC32F460 USB CDC通信异常:非对齐访问异常排查 20260413-Hyperbridge 攻击事件:发生在默克尔山上的验证绕过 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 深度学习进阶(八)Swin Transformer 最小二乘问题详解19:带先验约束的增量式SFM优化与实现 SnapTranslate 3.0 正式发布:全局划词翻译 + 完整英语学习闭环,一站式搞定查词、记词、复习 工作的意义、工作的困难认知再思考 .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 开了 TUN 模式还是直连?90% 的人都踩过这个坑 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术
京东二面:Redis的使用场景有哪些?别说你只用过缓存
苏三说技术 · 2026-05-07 · via 博客园_首页

前言

最近面试季,好多小伙伴都反馈同一个问题:“面试官问我Redis的使用场景,我只说了缓存,结果当场被怼——‘就这?’”

其实,Redis远不止“缓存”这么简单。

它是一个多才多艺的选手,凭借内存读写、丰富的数据结构、原子操作、持久化、高可用等特性,几乎渗透到了后端开发的所有角落。

今天这篇文章就专门跟大家一起聊聊Redis的11种使用场景,希望对你会有所帮助。

更多项目实战在Java突击队网:susan.net.cn/project

场景一:高速缓存(最经典)

业务场景

查询商品详情、用户信息等高频读数据,把数据库扛不住的读压力放到Redis。

代码示例(旁路缓存模式)

@Service
public class ProductService {
    @Autowired
    private RedisTemplate<String, Product> redisTemplate;
    @Autowired
    private ProductMapper productMapper;

    public Product getProduct(Long id) {
        String cacheKey = "product:" + id;
        // 1. 读缓存
        Product product = redisTemplate.opsForValue().get(cacheKey);
        if (product != null) {
            return product;
        }
        // 2. 缓存未命中,查DB
        product = productMapper.selectById(id);
        if (product != null) {
            // 3. 写缓存,随机过期时间防雪崩
            int expire = 300 + new Random().nextInt(60);
            redisTemplate.opsForValue().set(cacheKey, product, expire, TimeUnit.SECONDS);
        }
        return product;
    }
}

优点:性能从几十毫秒降到亚毫秒级,能扛极高并发。
缺点:存在短时间数据不一致(最终一致性)。
适用场景:商品详情、配置信息、用户会话等读多写少的数据。

场景二:分布式锁

业务场景

秒杀扣库存、订单防重、定时任务防重复执行——多进程争抢同一资源时,需要一把全局锁。

推荐方案:Redisson(自动续期、可重入)

@Service
public class SeckillService {
    @Autowired
    private RedissonClient redissonClient;

    public void doSeckill(Long userId, Long productId) {
        String lockKey = "lock:seckill:" + productId;
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 尝试加锁,最多等待3秒,锁默认30秒(看门狗自动续期)
            if (lock.tryLock(3, TimeUnit.SECONDS)) {
                // 扣库存逻辑...
                int stock = getStock(productId);
                if (stock > 0) {
                    updateStock(productId, stock - 1);
                } else {
                    throw new RuntimeException("已售罄");
                }
            } else {
                throw new RuntimeException("系统繁忙,请稍后再试");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

⚠️ 新手坑:直接用SET NX EX,容易忘了续期或释放锁。强烈建议用Redisson。

优点:自动续期,可重入,支持主从/哨兵/集群。
缺点:引入额外客户端,比原生命令重一点。
适用场景:任何需要互斥的分布式操作。

场景三:计数器 & 限流器

业务场景

统计页面PV、接口调用次数、短信发送频率控制。

固定窗口限流(最简单的实现)

public boolean isAllowed(String userId) {
    String key = "rate:sendSms:" + userId;
    Long count = redisTemplate.opsForValue().increment(key);
    if (count == 1) {
        redisTemplate.expire(key, 60, TimeUnit.SECONDS);
    }
    return count <= 5;  // 每分钟最多5次
}

优点:原子操作,性能极高。
缺点:固定窗口存在临界突刺(边界处可能两倍流量)。更严格的可用滑动窗口(ZSET实现)。
适用场景:API限流、短信验证码、登录错误次数。

场景四:排行榜 / 有序集合

业务场景

游戏积分榜、热搜榜单、销量排行。

使用Sorted Set

// 添加玩家分数
redisTemplate.opsForZSet().add("rank:game:202605", "player:1001", 9980);
redisTemplate.opsForZSet().add("rank:game:202605", "player:1002", 10200);

// 获取前三名(降序)
Set<ZSetOperations.TypedTuple<String>> top3 =
    redisTemplate.opsForZSet().reverseRangeWithScores("rank:game:202605", 0, 2);

优点:自动排序,查询极快(O(logN))。
缺点:内存占用随数据量线性增长。
适用场景:实时排行榜、热点文章、商品热销榜。

场景五:最新动态 / 时间线

业务场景

微博时间线、Feed流、最新评论。

使用List(左侧推入,右侧截取)

// 发表一条新动态
String feedKey = "feeds:user:" + userId;
redisTemplate.opsForList().leftPush(feedKey, JSON.toJSONString(post));
// 只保留最近100条
redisTemplate.opsForList().trim(feedKey, 0, 99);

优点:写入快,分页方便。
缺点:无法做复杂排序,且只能按时间倒序。
适用场景:简单的“最新N条”列表,如用户动态、通知。

场景六:社交关系(集合运算)

业务场景

共同关注、好友推荐、可能认识的人。

// 用户A关注的人
redisTemplate.opsForSet().add("follow:1001", "1002", "1003", "1004");
// 用户B关注的人
redisTemplate.opsForSet().add("follow:1002", "1003", "1005");

// 共同关注
Set<String> intersect = redisTemplate.opsForSet().intersect("follow:1001", "follow:1002");
// 推荐关注(B关注但A未关注)
Set<String> diff = redisTemplate.opsForSet().difference("follow:1002", "follow:1001");

优点:集合运算毫秒级,代码简洁。
缺点:大key(比如千万粉丝)会导致慢查询。
适用场景:社交关系、权限标签、黑白名单。

场景七:轻量级消息队列(Stream / List)

业务场景

异步处理、削峰填谷、日志收集。

使用Redis 5.0+ Stream(支持消费组)

// 生产者
Map<String, String> msg = new HashMap<>();
msg.put("orderId", "ORD-123");
redisTemplate.opsForStream().add("order:stream", msg);

// 消费者
List<MapRecord<String, Object, Object>> records =
    redisTemplate.opsForStream().read(Consumer.from("order-group", "c1"),
        StreamReadOptions.empty().count(10),
        StreamOffset.create("order:stream", ReadOffset.lastConsumed()));

优点:无需额外组件,支持ACK、消费者组。
缺点:持久化可靠性不如RocketMQ/Kafka。
适用场景:内部任务分发、异步通知、不要求严格有序的场景。

场景八:布隆过滤器(防缓存穿透)

业务场景

拦截恶意请求,过滤肯定不存在的数据,避免打到数据库。

使用Redisson布隆过滤器

RBloomFilter<String> bloom = redissonClient.getBloomFilter("filter:productId");
bloom.tryInit(1000000L, 0.01); // 容量100万,误判率1%
// 初始化时把合法ID加入
for (Long id : allProductIds) {
    bloom.add(id.toString());
}

// 查询前先过滤
if (!bloom.contains(productId.toString())) {
    return null;  // 直接返回空,不查DB
}

优点:内存占用极小(1亿条仅约120MB)。
缺点:有误判率(宁可错杀一千,不放过一个)。
适用场景:防止恶意穿透、爬虫IP去重、黑名单过滤。

场景九:轻量级NoSQL(Hash存储对象)

业务场景

存储动态属性、用户Session、配置信息。

// 存储用户信息
Map<String, String> user = new HashMap<>();
user.put("name", "张三");
user.put("age", "28");
redisTemplate.opsForHash().putAll("user:1001", user);

// 获取单个字段
String name = (String) redisTemplate.opsForHash().get("user:1001", "name");
// 修改单个字段
redisTemplate.opsForHash().put("user:1001", "age", "29");

优点:比JSON序列化整个对象更节省内存,支持部分更新。
缺点:hash结构不适合深层次嵌套。
适用场景:用户资料、购物车(field为商品ID,value为数量)。

场景十:数据去重 / 唯一性判断

业务场景

UV统计、不能重复参加的抽奖、防重复提交。

使用Set或HyperLogLog

// 方式1:Set(精确但内存大)
Boolean success = redisTemplate.opsForSet().add("draw:202605", userId);
if (Boolean.TRUE.equals(success)) {
    // 第一次参加
}

// 方式2:HyperLogLog(内存极小,有误差)
redisTemplate.opsForHyperLogLog().add("uv:20260501", userId);
Long uv = redisTemplate.opsForHyperLogLog().size("uv:20260501");

优点:Set保证绝对精确;HyperLogLog内存极省(12KB)。
缺点:HyperLogLog有0.81%误差,不适合精确计数。
适用场景:抽奖去重、日活统计、爬虫URL去重。

场景十一:延时队列(使用Sorted Set)

业务场景

订单30分钟未支付自动取消、延迟通知。

// 添加延时任务(score为执行时间戳)
long execTime = System.currentTimeMillis() + 30 * 60 * 1000;
redisTemplate.opsForZSet().add("delay:order", orderId, execTime);

// 消费者定时扫描
Set<String> tasks = redisTemplate.opsForZSet().rangeByScore("delay:order", 0, System.currentTimeMillis());
for (String orderId : tasks) {
    // 处理超时订单
    if (redisTemplate.opsForZSet().remove("delay:order", orderId) > 0) {
        cancelOrder(orderId);
    }
}

优点:精准到毫秒,实现简单。
缺点:需要定时轮询,数据量大时性能下降。
适用场景:订单超时、定时提醒、会话过期清理。

更多项目实战在Java突击队网:susan.net.cn/project

总结

Redis不是只能做缓存。

当你遇到以下问题时,可以优先想想Redis:

  • 快不快? → 缓存、计数器
  • 要不要排队? → 消息队列
  • 要不要去重? → 集合、布隆过滤器
  • 要不要按分数排名? → Sorted Set
  • 多机器抢资源? → 分布式锁

下面是一张速查表,方便你回忆:

场景 数据结构 核心命令
缓存 String GET/SET
分布式锁 String + Redisson SET NX / tryLock
计数器 String INCR
排行榜 ZSET ZADD, ZREVRANGE
最新动态 List LPUSH, LTRIM
共同关注 Set SINTER, SDIFF
消息队列 Stream XADD, XREADGROUP
布隆过滤 -> Redisson RBloomFilter
对象存储 Hash HMSET, HGET
UV去重 HyperLogLog PFADD, PFCOUNT
延时队列 ZSET ZADD, ZRANGEBYSCORE

最后,送大家一句话:Redis的数据结构就是你的武器库,用对结构,往往能事半功倍。

希望这11个场景能帮你打开思路,下次面试时遇到“Redis能做什么”的问题,你可以自信地展开聊上十分钟。