提供实际开发中一致性实现的设计思路
分布式系统下数据一致性问题
在集中式系统中,要保证多个数据操作的一致性,可以直接使用事务+锁来管理保证数据的ACID。但是在分布式系统中要怎么保证多台机器之间的数据复制操作的一致性呢?
例1:一个购票系统现有A/B两个节点,用户1在A节点购票,用户2在B节点购票,但是现在库存中只有一张车票了,那么我们就得保证在用户1购票过程中用户2就得处于等待状态,等到用户1完成操作后用户2再查询库存
例2:A/B两个系统,A是订单系统,B是库存系统,当我们在A系统完成下单操作后要保证B系统的库存发生对应变化,当其中某个系统发生异常后除了回滚当前系统的数据还要保证异构系统的数据回滚
如何能既保证数据一致性,又保证系统的性能,是每一个分布式系统都需要考虑和权衡的。一致性模型可以在做这些提供一些思路
数据一致性模型
1.强一致性
强一致性可以理解为在任意时刻,所有节点中的数据是一样的。在同一个时间节点下,在节点A获取到的key1和节点B获取到的key1是完全相同的,这种方案对于用户是最为友好的,但是对于系统性能影响较大,例1就是强一致性的应用场景。
PS:zookeeper集群的主备一致性就是强一致性模型的实现,1)leader节点接收到请求,将事务加入事务队列,并且将事务广播给各个follower节点;2)follower接收事务并加入都事务队列,然后向leader发送准备提交请求;3)leader 接收到半数以上的准备提交请求后,提交事务同时向follower 发送提交事务请求;4)follower提交事务
2.弱一致性
系统不保证续进程或者线程的访问都会返回最新更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体承诺多久之后可以读到。但会尽可能保证在某个时间级别之后,可以让数据达到一致性状态。适用于某些一致性要求较低的场景。
PS:一些业务端的异步操作任务,任务提交完成后状态就处于执行中,客户端不会主动刷新状态,在获取任务结果时会进行一致性检查
3.最终一致性
就是不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间推移,所有节点的数据最终都会保持一致性,最终一致性是弱一致性的一个衍生方案
PS:DNS系统,由于DNS多级缓存的实现,所以修改DNS记录后不会在所有DNS服务节点生效,需要等待DNS服务器缓存过期后向源服务器更新新的记录才能实现,在节点获取数据时会做查询校验