专栏名称: 终码一生
提供免费JB账号,激活码,破解工具下载;分享Java开发技术(JVM,多线程,高并发,性能调优),开源项目,常见开发问题和前沿科技资讯等!
目录
相关文章推荐
月光博客  ·  《暗黑破坏神3》第35赛季开荒指南 ·  9 小时前  
看雪学苑  ·  议程大公开,精彩内容抢先看 | ... ·  昨天  
中国城市报  ·  白象食品道歉 ·  22 小时前  
计算机与网络安全  ·  XX大学网络安全突发事件应急预案 ·  昨天  
云技术  ·  88万元,数据可视化系统大单:帆软中标 ·  2 天前  
云技术  ·  88万元,数据可视化系统大单:帆软中标 ·  2 天前  
51好读  ›  专栏  ›  终码一生

用好缓存的10条军规

终码一生  · 公众号  · 科技自媒体 互联网安全  · 2025-06-02 21:41

主要观点总结

本文介绍了使用缓存的10条军规,包括避免大key、设置过期时间、避免批量失效、增加熔断降级、空值缓存、分布式锁用Redisson、延迟双删策略、最终一致性方案、热点数据预加载和根据场景选择数据结构等。

关键观点总结

关键观点1: 避免大key

大对象缓存会导致内存碎片化,甚至触发Full GC。建议将基础信息(如用户ID、名称)与扩展信息(如订单记录)分离存储。

关键观点2: 设置过期时间

缓存数据需要设置过期时间,避免数据不一致。TTL设置公式:最优TTL = 平均数据变更周期 × 0.3。可以使用动态TTL策略,如电商商品详情页可设置30分钟基础TTL+随机5分钟抖动。

关键观点3: 避免批量失效

使用基础TTL + 随机抖动的方案,解决缓存集中失效导致数据库被打爆的问题。

关键观点4: 增加熔断降级

使用熔断降级策略,防止缓存挂掉影响服务可用性。Hystrix实现示例。

关键观点5: 空值缓存

在用户请求并发量大的业务场景中,把空值缓存起来,防止直接查询数据库。

关键观点6: 分布式锁用Redisson

使用Redisson做分布式锁,解决Redis分布式锁可能遇到的问题。

关键观点7: 延迟双删策略

在保证数据库和缓存双写数据一致性的业务场景中,使用延迟双删策略。

关键观点8: 最终一致性方案

基于Binlog的方案,DB更新数据后,Canal自动监听数据变化并发送MQ消息,在MQ消费者中删除缓存。

关键观点9: 热点数据预加载

提前做热点数据的预加载,实时监控方案包括使用Redis HyperLogLog统计访问频率和定时任务检测热点。

关键观点10: 根据场景选择数据结构

选择合适的数据结构存储数据,如String、Hash、List、Set和ZSet等,根据场景选择最佳实践。


正文

请到「今天看啥」查看全文


军规3: 避免批量失效

典型事故
所有缓存设置相同TTL,导致每天凌晨集中失效,数据库瞬时被打爆。

解决方案

使用基础TTL + 随机抖动的方案:

publiclongrandomTtl(long baseTtl){  
    return baseTtl + new Random().nextInt(300); 
}  

TTL增加0-5分钟随机值。

使用示例

redisTemplate.opsForValue().set(key, value, randomTtl(1800), TimeUnit.SECONDS);

失效时间分布

图片

军规4: 需要增加熔断降级

我们在使用缓存的时候,需要增加熔断降级策略,防止万一缓存挂了,不能影响整个服务的可用性。

Hystrix实现示例

@HystrixCommand(fallbackMethod = "getProductFallback",  
               commandProperties = {  
                   @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),  
                   @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000")  
               })  
public Product getProduct(Long id){  
    return productDao.findById(id);  
}  

public Product getProductFallback(Long id){  
    returnnew Product().setDefault(); // 返回兜底数据  
}

熔断状态机

图片

▶ 军规5: 空值缓存

在用户请求并发量大的业务场景种,我们需要把空值缓存起来。

防止大批量在系统中不存在的用户id,没有命中缓存,而直接查询数据库的情况。

典型代码

public Product getProduct(Long id){  
    String key = "product:" + id;      Product product = redis.get(key);      if (product != null) {          if (product.isEmpty()) { // 空对象标识              returnnull;          }          return product;      }      product = productDao.findById(id);      if (product == null) {          redis.setex(key, 300"empty"); // 缓存空值5分钟          returnnull;      }      redis.setex(key, 3600, product);      return product;  }

空值缓存原理

图片

需要将数据库中返回的空值,缓存起来。

后面如果有相同的key查询数据,则直接从缓存中返回空值。

而无需再查询一次数据库。

军规6: 分布式锁用Redisson







请到「今天看啥」查看全文