news 2026/6/12 9:29:39

Java-Redis 缓存「从入门到黑科技」2026 版

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java-Redis 缓存「从入门到黑科技」2026 版

一篇看懂:缓存模型 → 实战代码 → 高阶玩法 → 暗黑黑科技 所有示例基于 Spring Boot 3 & Redis 7,复制即可跑。

一、概念速览:4 种缓存模式一张图

模式

谁来写缓存

一致性

适用场景

Cache Aside

应用自己

中等

读多写少,最常用

Read Through

Redis 插件

较好

读多,缓存层透明

Write Through

同步写 DB+缓存

写多,强一致

Write Behind

先写缓存,异步刷盘

最高吞吐

计数器、秒杀

二、Spring Boot 3 快速落地(Cache Aside)

1.依赖 & 配置

spring: redis: host: localhost port: 6379 cache: type: redis # 开启 Spring Cache redis: time-to-live: 3600s key-prefix: demo use-key-prefix: true

2.启动类加 @EnableCaching

3.业务代码(零侵入)

@Service public class ProductService { @Cacheable(value = "product", key = "#id") public Product getProduct(Long id) { return dao.selectById(id); // 缓存未命中才走 DB } @CacheEvict(value = "product", key = "#id") public void updateProduct(Long id, Product p) { dao.updateById(id, p); } }

效果:第一次查 DB,后续 1h 内直接走 Redis;更新时自动失效。

三、进阶:手写 RedisTemplate 模板(细粒度控制)

@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory f) { RedisTemplate<String, Object> t = new RedisTemplate<>(); t.setConnectionFactory(f); // 序列化 GenericJackson2JsonRedisSerializer json = new GenericJackson2JsonRedisSerializer(); t.setKeySerializer(RedisSerializer.string()); t.setValueSerializer(json); t.setHashKeySerializer(RedisSerializer.string()); t.setHashValueSerializer(json); return t; } }

工具类封装:

@Component public class RedisUtil { @Resource private RedisTemplate<String, Object> redisTemplate; public void set(String k, Object v, long seconds) { redisTemplate.opsForValue().set(k, v, Duration.ofSeconds(seconds)); } public <T> T get(String k, Class<T> clazz) { return (T) redisTemplate.opsForValue().get(k); } public boolean exists(String k) { return Boolean.TRUE.equals(redisTemplate.hasKey(k)); } }

使用:

String key = "product:" + id; Product p = redisUtil.get(key, Product.class); if (p == null) { p = dao.selectById(id); redisUtil.set(key, p, 3600); }

四、高并发三板斧

1. 分布式锁(防超卖)

public boolean deductStock(Long id, int num) { String lockKey = "lock:stock:" + id; String uuid = Thread.currentThread().getId() + ":" + System.nanoTime(); Boolean ok = redisTemplate.opsForValue() .setIfAbsent(lockKey, uuid, 10, TimeUnit.SECONDS); if (!Boolean.TRUE.equals(ok)) return false; try { int stock = Integer.parseInt(redisTemplate.opsForValue().get("stock:" + id)); if (stock < num) return false; redisTemplate.opsForValue().decrement("stock:" + id, num); return true; } finally { // 用 Lua 保证“自己的锁自己解” String script = "if redis.call('get',KEYS[1])==ARGV[1] then " + "return redis.call('del',KEYS[1]) else return 0 end"; redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Collections.singletonList(lockKey), uuid); } }

2. 布隆过滤器(防穿透)

RBloomFilter<String> bloomFilter = redisson.getBloomFilter("user-filter"); bloomFilter.tryInit(1_000_000, 0.01); // 100w 容量,1% 误判 // 初始化合法 ID userIds.forEach(id -> bloomFilter.add(id)); // 查询时先过过滤器 if (!bloomFilter.contains(requestUserId)) { throw new RuntimeException("非法 ID"); }

3. 雪崩 + 击穿双保险

  • 随机 TTL:ttl = base + Random(0~600) 打散过期

  • 热点永不过期 + 异步刷新: 设置物理过期 = 逻辑过期 + 30min,后台线程提前 10min 更新缓存 。

五、黑科技:把缓存玩成“中间件”

1. 双写一致性 → 基于 Canal 的异步最终一致

  1. MySQL 开 binlog

  2. Canal 监听变更 → MQ → 应用更新 Redis 结果:应用只写 DB,缓存零耦合,延迟 <1s。

2. 大 Key 实时扫描 + 自动拆分

// 利用 MEMORY USAGE 命令扫描 public List<BigKeyInfo> scanBigKeys() { Cursor<byte[]> cursor = redisTemplate.executeWithStickyConnection( conn -> conn.scan(ScanOptions.scanOptions().count(1000).build())); List<BigKeyInfo> big = new ArrayList<>(); while (cursor.hasNext()) { String k = new String(cursor.next()); long mem = redisTemplate.execute( (RedisCallback<Long>) con -> con.memoryUsage(k.getBytes())); if (mem > 1024 * 1024) big.add(new BigKeyInfo(k, mem)); } return big; }

发现后 按日期/哈希拆表 或改用 redis.hset 分桶 。

3. Pipeline 批量打榜(万次读写 1s 完成)

List<Object> pipe = redisTemplate.executePipelined((RedisCallback<Object>) conn -> { for (int i = 0; i < 10000; i++) { conn.setEx(("key" + i).getBytes(), 300, ("val" + i).getBytes()); } return null; });

单条 1ms → 批量 0.1μs,QPS 提升 100+ 倍 。

4. Redis + Lua 实现秒杀库存扣减(原子 + 0 超卖)

-- stock.lua local stock = tonumber(redis.call('get', KEYS[1])) if stock <= 0 then return -1 end redis.call('decr', KEYS[1]) return stock

Java 侧仅一次 redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), keys),网络 RTT 最小化。

5. 二级缓存(本地 Caffeine + Redis)

思路:L1 进程级 μs,L2 全局共享;L1 miss → L2 → DB,L2 变更发广播清 L1。 实现:Spring Cache 支持多提供者,开箱即用。

六、常见翻车现场 & 急救方案

问题

现象

急救药

缓存雪崩

瞬时 QPS 全打 DB

随机 TTL + 热点永不过期 + 异步刷新

缓存穿透

非法 ID 持续请求

布隆过滤器 + 空值缓存

缓存击穿

热点 Key 失效瞬间

互斥锁(setIfAbsent)+ 逻辑过期

大 Key

阻塞主从同步

扫描拆分,用 hash/分桶

双写不一致

DB≠缓存

延迟双删 / Canal 异步最终一致

七、总结脑图(文字版)

Java-Redis 缓存 ├─ 4 种模式:Aside / Read|Write Through / Write Behind ├─ Spring 落地:@Cacheable + RedisTemplate ├─ 高并发三件套:分布式锁 + 布隆过滤器 + 雪崩/击穿防护 └─ 黑科技:Canal 异步一致 / 大 Key 自动拆 / Pipeline 批量 / Lua 0 超卖 / 二级缓存

收藏这篇,面试、调优、高并发都能打!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 22:47:27

语音合成中的显存占用优化:GLM-TTS在10GB显卡上的运行实录

语音合成中的显存占用优化&#xff1a;GLM-TTS在10GB显卡上的运行实录 在AI语音技术飞速发展的今天&#xff0c;越来越多的开发者希望将高质量语音合成功能集成到本地应用或轻量级服务中。然而现实往往骨感——许多先进的TTS模型动辄需要24GB甚至更高的显存&#xff0c;让RTX 3…

作者头像 李华
网站建设 2026/6/10 16:14:39

基于GLM-TTS的情感语音合成方案,打造拟人化AI主播

基于GLM-TTS的情感语音合成方案&#xff0c;打造拟人化AI主播 在短视频平台日均内容产出破亿的今天&#xff0c;一个冷冰冰的机械音已经很难留住用户的耳朵。观众不再满足于“能听清”&#xff0c;而是期待“听得进去”——语气中的情绪起伏、语调里的专业感、甚至一句话尾音的…

作者头像 李华
网站建设 2026/6/8 9:27:26

如何清理显存?GLM-TTS内置工具帮你释放GPU资源

如何清理显存&#xff1f;GLM-TTS内置工具帮你释放GPU资源 在本地部署大模型的日常中&#xff0c;你是否遇到过这样的场景&#xff1a;语音合成任务早已结束&#xff0c;但显卡监控依然显示 GPU 显存被“锁死”在 10GB 以上&#xff1f;重启服务太麻烦&#xff0c;不处理又影响…

作者头像 李华
网站建设 2026/6/5 22:19:37

测试脚本维护成本高?试试“自愈式定位器”技术

测试脚本维护的痛点与革新机遇在软件测试领域&#xff0c;自动化测试脚本的维护成本居高不下&#xff0c;已成为从业者的“阿喀琉斯之踵”。据统计&#xff0c;超过60%的测试团队将50%以上的时间耗费在脚本修复上&#xff0c;而非新功能测试——这源于UI频繁变更、环境依赖性强…

作者头像 李华
网站建设 2026/6/11 20:30:26

2026年,测试覆盖率不再是KPI,AI预测风险才是

测试度量标准的时代更迭 当微软Azure测试团队在2025年发布《智能质量白皮书》时&#xff0c;一组数据引发行业震动&#xff1a;采用AI风险预测模型的系统&#xff0c;生产环境故障率比依赖80%测试覆盖率的团队降低47%。这标志着软件测试领域迎来价值锚点的根本转移——从追求覆…

作者头像 李华
网站建设 2026/6/8 12:29:15

‌自动化脚本的可持续性挑战与优化策略

在快速迭代的软件开发环境中&#xff0c;自动化测试脚本是质量保障的核心工具。然而&#xff0c;许多测试从业者面临一个尖锐问题&#xff1a;精心编写的脚本在下一次发布时突然失效&#xff0c;导致测试延迟、缺陷遗漏&#xff0c;甚至团队信任危机。标题“你写的自动化脚本&a…

作者头像 李华