保证双写一致性?;
1,延迟双写:更新时先更新数据库,删除缓存,;下次读取时更新缓存 缺点:
- 如果数据库写操作失败,应用可能需要回滚其他已完成的操作,这可能导致复杂性。
- 对于高并发系统,缓存可能在数据被写入数据库后和被删除之前被多次访问,导致脏读。
2,使用队列;
-
写操作:
- 当有一个更新操作时,首先将它放入一个消息队列(如 Kafka、RabbitMQ)。
- 在此期间,缓存可以被标记为"脏"或直接被清除,以防止脏读。
-
队列消费者:
- 消费者从队列中取出更新操作。
- 消费者首先更新数据库。
- 确保数据库更新成功后,消费者再更新缓存。
-
读操作:
- 首先从缓存中读取数据。
- 如果缓存中没有数据或被标记为"脏",则从数据库中读取。
优点:
- 通过序列化更新操作,确保数据库和缓存的更新顺序一致。
- 可以容忍短时间的不一致,因为最终一致性会被保证。
局限性:
- 引入消息队列增加了系统的复杂性。
- 可能会增加延迟,因为更新操作需要经过消息队列。
3, 牺牲性能,使用分布式锁;;
- Redis:Redis提供了分布式锁的实现,例如使用
SETNX
命令。 - Zookeeper:Zookeeper的
Ephemeral Sequential
节点可以用来实现分布式锁。 - etcd:etcd提供了对分布式锁的原生支持。