- 分布式系统
- 理论
从ACID到CAP/BASE
事务(Transaction)是由一系列对系统中数据进行访问和更新的操作所组成的一个程序执行逻辑单元(Unit),狭义上的事务指数据库事务。事务需要满足ACID特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
分布式事务可以看作由多个分布式操作组成的序列,每个操作称为子事务。在高并发的互联网应用中,如果实现要实现严格满足ACID特性的分布式事务,会出现可用性与一致性之间的冲突。
CAP理论
一个分布式系统不可能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partitiontolerance)这三个特性,最多只能同时满足其中的两项。由于分区容错性是分布式系统最基本的需求,所以往往需要把精力花在如何根据业务特点在一致性和可用性之间需求平衡。
一致性
分布式环境中,一致性是指数据在多个副本之间是否能保持一致的特性。如果能够做到针对一个数据项的更新操作执行成功后,所有的用户都可以读取到最新的值,即可认为该系统具有强一致性。
可用性
可用性是指系统提供的服务必须一致处于可用的状态,对于用户的每一次请求都能在响应时间内返回结果。
分区容错性
分布式系统在遇到任何网络分区故障时,仍然需要保证对外提供满足一致性和可用性的服务,除非整个网络环境都发生故障。
BASE理论
BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写。BASE是对CAP中一致性和可用性权衡的结果,来源于对大规模互联网系统分布式实践的总结,是基于CAP定理逐步演化而来的,其核心思想是即使无法做到强一致性(Strong consistency),但每个应用可以根据自身业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。
基本可用
基本可用是指分布式系统在出现不可预知故障时,允许损失部分可用性。如响应时间增加、不重要功能降级等。
软状态
和硬状态相比,软状态允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步过程存在延时
最终一致性
最终一致性是系统所有数据副本在经过一段时间的同步后,最终能够达到一个一致的状态,而不需要实时保证系统数据的一致性。工程实践中,最终一致性存在以下五类:
因果一致性(Causal consistency)
如果进程A在更新完某个数据项后通知了进程B,那么进程B之后对该数据项的访问都应该能够获取的进程A更新后的最新值,并且如果进程B要对该数据进行更新,必须基于进程A更新后的最新值,即不能发生丢失更新的情况。与此同时,与进程A无因果关系的进程C的数据访问则没有这样的限制。
读己之所写(Read your writes)
进程A更新一个数据项后,它自己总是能够访问到更新过的最新值,而不会看到旧值,可以看作一种特殊的因果一致性
会话一致性(Session consistency)
系统保证在同一个会话中实现读己之所写的一致性,用户端能够在同一个会话中始终读取到数据项的最新值
单调读一致性(Monotonic read consistency)
如果一个进程从系统中读取一个数据项的某个值后,系统对该进程后续的任何数据访问都不应该返回更旧的值
单调写一致性(Monotonic write consistency)
保证来自同一个进程的写操作被顺序地执行
BASE理论面向的是大型高可用高扩展的分布式系统,不同于ACID的强一致性模型,它采用牺牲强一致性来获得可用性,并允许数据在一段时间内不一致,但最终能达到一致状态。在实际分布式场景中,不同业务单元和组件对数据一致性的要求是不同的,ACID特性与BASE理论往往会结合在一起使用。
Paxos
用于达成共识性问题,即对多个节点产生的值,该算法能保证只选出唯一一个值。
主要有三类节点:
- 提议者(Proposer):提议一个值;
- 接受者(Acceptor):对每个提议进行投票;
- 告知者(Learner):被告知投票的结果,不参与投票过程。
算法过程:
prepare阶段:
- proposer选择一个提案编号n并将prepare请求发送给acceptors中的一个多数派;
- acceptor收到prepare消息后,如果提案的编号大于它已经回复的所有prepare消息(回复消息表示接受accept),则acceptor将自己上次接受的提案回复给proposer,并承诺不再回复小于n的提案;
批准阶段:
- 当一个proposer收到了多数acceptors对prepare的回复后,就进入批准阶段。它要向回复prepare请求的acceptors发送accept请求,包括编号n和根据P2c决定的value(如果根据P2c没有已经接受的value,那么它可以自由决定value)。
- 在不违背自己向其他proposer的承诺的前提下,acceptor收到accept请求后即批准这个请求。
发布阶段
acceptors需要将accept消息发送给learners的一个子集,然后由这些learners去通知所有learners