分布式系统的事务处理

2016/3/4 posted in  数据库

通常,我们会通过两种手段来扩展我们的数据服务:

  • 数据分区:把数据分块放在不同的服务器上
  • 数据镜像:让所有的服务器都有相同的数据,提供相当的服务

数据服务的高可用性只能通过第二种方法来完成--数据的冗余存储。但是,加入更多的机器,会让我们的数据服务变得很复杂,尤其是跨服务器的事务处理,也就是跨服务器的数据一致性。

数据一致性,简单说有三种类型:

  • Weak弱一致性:当你写入一个新值后,读操作在数据副本上可能读出来,也可能读不出来
  • Eventually最终一致性:当你写入一个新值后,有可能读不出来,但在某个时间窗口之后保证最终能读出来
  • Strong强一致性:新的数据一旦写入,在任意副本任意时刻都能读到新值

Master-Slave

  • 读写请求都由Master负责。

  • 写请求写到Master上后,由Master同步到Slave上。

Master同步到Slave上,你可以使用异步,也可以使用同步,可以使用Masterpush,也可以使用Slavepull。 通常来说是Slave来周期性的pull,所以,是最终一致性。

Master-Master

一个系统存在两个或多个Master,每个Master都提供read-write服务。这个模型是Master-Slave的加强版,数据间同步一般是通过Master间的异步完成,所以是最终一致性。

Two/Three Phase Commit

在分布式系统中,每个节点虽然可以知晓自己在操作时是成功还是失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点的时候,为了保持事务的ACID特征,需要引入一个座位协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交。

第一阶段
  • 协调者会问所有的参与者结点,是否可以执行提交操作。
  • 各个参与者开始事务执行的准备工作:如:为资源上锁,预留资源,写undo/redo log……
  • 参与者响应协调者,如果事务的准备工作成功,则回应“可以提交”,否则回应“拒绝提交”。
第二阶段
  • 如果所有的参与者都回应“可以提交”,那么,协调者向所有的参与者发送“正式提交”的命令。参与者完成正式提交,并释放所有资源,然后回应“完成”,协调者收集各结点的“完成”回应后结束这个Global Transaction
  • 如果有一个参与者回应“拒绝提交”,那么,协调者向所有的参与者发送“回滚操作”,并释放所有资源,然后回应“回滚完成”,协调者收集各结点的“回滚”回应后,取消这个Global Transaction

先尝试再提交

1)牧师分别问新郎和新娘:你是否愿意……不管生老病死……(询问阶段)
2)当新郎和新娘都回答愿意后(锁定一生的资源),牧师就会说:我宣布你们……(事务提交)

一些问题:

  • 其中一个是同步阻塞操作,会非常大地影响性能
  • Timeout
  • 如果第一阶段完成后,参与者在第二阶段没有收到决策,那么数据结点会进入不知所措的状态,这个状态会block住整个事务

Paxis算法

任何一个点都可以提出要修改某个数据的提案,是否通过这个提案取决于这个集群中是否有超过半数的结点同意(所以Paxos算法需要集群中的结点是单数)。

Reference

http://coolshell.cn/articles/10910.html