在微服务架构中,缓存一致性是保障数据准确性的核心挑战。本文将对比几种主流的同步机制,并提供可复现的解决方案。
双写机制
这是最直接的方式,在更新数据库的同时同步更新缓存:
@Transactional
public void updateUser(User user) {
userMapper.update(user);
cache.put("user:" + user.getId(), user);
}
但这种方式存在事务一致性风险,需要确保数据库和缓存操作在同一事务中。
延迟双删策略
先删除缓存,更新数据库,再延迟删除缓存:
public void updateUser(User user) {
cache.delete("user:" + user.getId());
userMapper.update(user);
Thread.sleep(500); // 延迟删除
cache.delete("user:" + user.getId());
}
适用于读多写少的场景,但会引入一定的延迟。
消息队列异步更新
通过消息中间件实现最终一致性:
public void updateUser(User user) {
userMapper.update(user);
// 发送更新消息到MQ
messageProducer.send("user.update", user.getId());
}
// 消费者处理
@RabbitListener(queues = "user.update")
public void handleUserUpdate(Long userId) {
User user = userMapper.findById(userId);
cache.put("user:" + userId, user);
}
该方案通过异步解耦,提高系统吞吐量。
架构建议
- 读多写少场景使用延迟双删
- 高并发场景采用消息队列
- 对一致性要求极高的业务使用双写机制
实践证明,合理的缓存策略需要结合业务特点进行选择。

讨论