主要观点总结
本文介绍了使用缓存的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