一、热点数据预加载
// 使用Redis HyperLogLog统计访问频率
public void recordAccess(Long productId) {
String key = "access:product:" + productId;
redis.pfadd(key, UUID.randomUUID().toString());
redis.expire(key, 60); // 统计最近60秒
}
// 定时任务检测热点
@Scheduled(fixedRate = 10000)
public void detectHotKeys() {
Set<String> keys = redis.keys("access:product:*");
keys.forEach(key -> {
long count = redis.pfcount(key);
if (count > 1000) { // 阈值
Long productId = extractId(key);
preloadProduct(productId);
}
});
}
二、空值缓存
public Product getProduct(Long id) {
String key = "product:" + id;
Product product = redis.get(key);
if (product != null) {
if (product.isEmpty()) { // 空对象标识
return null;
}
return product;
}
product = productDao.findById(id);
if (product == null) {
redis.setex(key, 300, "empty"); // 缓存空值5分钟
return null;
}
redis.setex(key, 3600, product);
return product;
}
三、需要增加熔断降级
@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) {
return new Product().setDefault(); // 返回兜底数据
}
四、延迟双删策略
@Transactional
public void updateProduct(Product product) {
// 1. 先删缓存
redis.delete("product:" + product.getId());
// 2. 更新数据库
productDao.update(product);
// 3. 延时再删
executor.schedule(() -> {
redis.delete("product:" + product.getId());
}, 500, TimeUnit.MILLISECONDS);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。