扫盲贴-分布式数据一致性:两阶段提交,三阶段提交

分布式一致性

分布式系统中,为保证数据的高可用,通常将数据保留多个副本,这些副本放置在不同的物理机上。

  • 什么是数据一致性

在数据有多副本的情况下,如果网络,服务器,软件本身故障,会导致部分副本写入成功,部分副本写入失败。造成各个副本之间数据不一致,数据内容冲突。

  • CAP定理

CAP理论认为:分布式环境下设计和部署系统保持3个核心需求:

一致性,可用性,可伸缩性

一致性:

这个和数据库ACID的一致性类似,但这里关注的所有数据节点的数据一致性和正确性,而数据库ACID关注的在一个事务内,对数据的约束。分布式环境中,更新操作执行后所有用户都应该读取到新值。

可用性:

每一个操作总是能够在一定时间内返回结果,系统必须就请求返回,必须有响应结果,成功或失败。

可伸缩性:

是否对数据进行区分,考虑到性能和业务伸缩性。

  • 数据一致模型

一些分布式系统通过复制数据提高系统可靠性和容错性,并且将数据的不同副本存放在不同机器。

强一致性:

当更新操作完成之后,任何多个后续进程或现场的访问都会返回最新结果。这种实时性会牺牲可用性。

弱一致性:

系统并不保证后续进程或现场的访问会返回最新更新结果。用户读到的数据可能不是最新,这段时间称为:不一致窗口。系统在数据写入成功之后,不承诺可读到最新值,不承诺多久可以读到。

最终一致性:

弱一致性的一种特例。系统保证在没有后续更新前提下,系统最终返回上一次更新结果值,在没有故障发生前提下,不一致窗口时间内,受通信延迟,系统负载和副本数量影响。DNS是一个最典型最终一致性系统。

典型分布式事务实例

跨行转账问题是一个典型的分布式事务,用户A向B的一个转账1000,要进行A的余额-1000,B的余额+1000,显然必须保证这两个操作的事务性。 类似的还有,电商系统中,当有用户下单后,除了在订单表插入记,还要在商品表更新库存等,特别是随着微服务架构的流行,分布式事务的场景更变得更普遍。

两阶段提交

两阶段提交协议是协调所有分布式原子事务参与者,并决定提交或取消(回滚)的分布式算法。

协议参与者

在两阶段提交协议中,系统一般包含两类机器(或节点):

  • 一类为协调者(coordinator),通常一个系统中只有一个;
  • 另一类为事务参与者(participants,cohorts或workers),一般包含多个,在数据存储系统中可以理解为数据副本的个数。
  • 协议中假设每个节点都会记录写前日志(write-ahead log)并持久性存储,即使节点发生故障日志也不会丢失。协议中同时假设节点不会发生永久性故障而且任意两个节点都可以互相通信。

两阶段执行

  • 1.请求阶段(commit-request phase,或称表决阶段,voting phase) 在请求阶段,协调者将通知事务参与者准备提交或取消事务,然后进入表决过程。 在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。
  • 2.提交阶段(commit phase) 在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。 当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行响应的操作。

两阶段提交缺点

  • 1.同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。 当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。
  • 2.单点故障。由于协调者的重要性,一旦协调者发生故障。 参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)
  • 3.数据不一致。在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。

两阶段提交无法解决的问题

当协调者出错,同时参与者也出错时,两阶段无法保证事务执行的完整性。 考虑协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。 那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。

三阶段提交

三阶段提交协议在协调者和参与者中都引入超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。

三阶段执行

  • CanCommit阶段

3阶段CanCommit阶段和2阶段准备阶段很像。 协调者向参与者发送Commit请求,参与者如果可以提交就Yes响应,否则No响应。

  • PreCommit阶段

根据第一阶段反应情况决定执行PreCommit操作。

如Yes:就进行事务的预执行:

发送预提交请求,进入Prepared阶段。 事务预提交,执行事务操作,将undo和redo信息记录到事务日志中。 响应反馈,如果事务成功执行,等待最终指令。

如果No,或等待超时:中断事务:

发送中断请求。 中断事务。

  • DoCommit阶段

该阶段进行真正的事务提交,两种情况:

执行提交:

发送提交请求,将从鱼提交进入提交状态。 事务提交,上面执行成功执行正式的事务提交。在事务提交之后释放事务资源。 响应反馈,事务提交之后反馈。 完成事务。收到反馈之后,完成事务。

中断事务:

没有收到反馈,中断事务。

三阶段两阶段的不同

两阶段在准备阶段和提交阶段之间,插入预提交阶段,使三阶段变成CanCommit,PreCommit,DoCommit阶段。 PreCommit是一个缓存,保证在最后提交阶段之前各个节点状态一致的。

  • 目前还有一种重要的算法就是Paxos算法,Zookeeper采用的就是Paxos算法的改进。*

原文发布于微信公众号 - 服务端技术杂谈(ITIBB2014)

原文发表时间:2016-10-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

周集:好用的工具和网站

上次提到的软件下载的页面已经写完了,接下来就是往页面中丰富内容,我会放一些自己用过的比较好用的软件工具,下载地址,有官方网站的我会放上官方网站的地址,没有的话,...

2209
来自专栏微信小开发

整合微信小程序的Web API接口层的架构设计

来源:伍华聪 cnblogs.com/wuhuacong/p/7267333.html 例如:《C#开发微信门户及应用--微信各个项目模块的定义和相互关系》介绍...

38910
来自专栏Rainbond开源「容器云平台」

云帮每周更新日志(2017.01.02~2017.01.15)

1694
来自专栏携程技术中心

开源 | 携程Redis多数据中心解决方案-XPipe

作者简介 孟文超,携程技术中心框架研发部高级经理。2016年加入携程,目前主要负责Redis多数据中心项目XPipe。此前曾在大众点评工作,任基础架构部门通信团...

56610
来自专栏黑泽君的专栏

GitHub上如何创建组织?

如何创建组织?   有时在团队协作中,当需要用到多个代码仓库时,就需要一个github的组织了。 github组织允许你管理和组织所有的代码仓库。一个git...

3344
来自专栏Java架构沉思录

CDN为什么这么快

CDN全称:Content Delivery Network或Content Ddistribute Network,即内容分发网络。

3972
来自专栏Java架构沉思录

微服务架构下静态数据通用缓存机制

在分布式系统中,特别是最近很火的微服务架构下,有没有或者能不能总结出一个业务静态数据的通用缓存处理机制或方案,这篇文章将结合一些实际的研发经验,尝试理清其中存在...

862
来自专栏.NET技术

关于分布式事务、两阶段提交协议、三阶提交协议

随着大型网站的各种高并发访问、海量数据处理等场景越来越多,如何实现网站的高可用、易伸缩、可扩展、安全等目标就显得越来越重要。

3512
来自专栏华章科技

关于小程序,我只服这篇文章

微信小程序能实现的事务,App理论上都能实现;但App能实现的功能,微信小程序却受限于框架与微信开放的API,就不一定能做。

1053
来自专栏WeTest质量开放平台团队的专栏

微信支付异常性能测试

? 作 者 尹华乐,腾讯微信事业群工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。 一、异常压测场景模拟 说明:压测服务器具备自动...

1681

扫码关注云+社区

领取腾讯云代金券