地缓存与 Redis 的数据一致性方案
本地缓存(如 Caffeine、Guava)与 Redis 组成的双层缓存架构,在提升性能的同时也带来了数据一致性的经典难题。由于本地缓存是进程内存储,当数据在 Redis 或数据库中更新时,如何同步更新所有应用实例的本地缓存,成为分布式系统中的核心挑战。一、问题本质:为什么会出现不一致?1.1 不一致的根源核心矛盾:本地缓存是“私有”的:每个应用实例独立存储,互不可见数据更新是“共享”的:通过数据库或 Redis 统一修改缺乏跨实例通知机制:实例 A 更新数据后,实例 B、C 的本地缓存无法感知1.2 一致性级别选择一致性级别说明适用场景代价强一致性任何时刻所有节点数据相同金融、库存扣减性能极差,几乎不可行最终一致性短暂不一致后达到一致大部分业务场景可接受,需设计同步机制弱一致性允许长时间不一致配置类、非敏感数据风险高核心结论:在双层缓存架构中,强一致性是不现实的。目标是实现可接受时间窗口内的最终一致性(通常 100ms ~ 5s)。二、主流一致性方案2.1 方案一:Redis 消息通知(Pub/Sub)核心思想:数据更新时,通过 Redis 的 Pub/Sub 发布消息,所有订阅该频道的应用实例收到通知后失效或更新本地缓存。实现代码:java@Service public class CacheConsistencyService { @Autowired private RedisTemplateString, Object redisTemplate; @Autowired private CacheString, Object localCache; private static final String CACHE_TOPIC = "cache:invalidate"; // 更新数据时调用 @Transactional public void updateProduct(Product product) { // 1. 更新数据库 productMapper.updateById(product); // 2. 更新 Redis String redisKey = "product:" + product.getId(); redisTemplate.opsForValue().set(redisKey, product); // 3. 发布失效消息 redisTemplate.convertAndSend(CACHE_TOPIC, redisKey); } // 消息监听器:接收失效通知 @Component public static class CacheInvalidateListener implements MessageListener { @Autowired private CacheString, Object localCache; @Override public void onMessage(Message message, byte[] pattern) { String key = new String(message.getBody()); localCache.invalidate(key); // 失效本地缓存 log.debug("收到失效通知,已清除本地缓存: {}", key); } } }优缺点分析:优点缺点✅ 实时性好(毫秒级)❌ Redis Pub/Sub 不持久化,消息可能丢失
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2516361.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!