分布式系统数据一致性详解

分布式系统数据一致性详解

问题背景

随着业务规模的增长,单应用和单数据库已经无法支撑,这时我们可能就会进行服务拆分、数据库拆分等来缓解单点压力。但这时数据存储于不同的事务单元但又要保证同步数据,这时就产生了分布式系统的数据一致性问题。
分布式一致性目前有SOA一致性问题、多数据源一致性问题。常见场景如下:

  • 场景A:传统业务数据库瓶颈的分库方案
    比如订单和积分表分在两台机器的两个库中,完成订单后需要增加积分。
  • 场景B:跨项目的基于中间库的协作方案
    项目组A需要读取项目组B的交易状态,项目组B新建新库,同步一份交易状态到新库中,供项目组A查询。这是要保证当前库和新库的一致性。
  • 场景C:soa/微服务化后部分数据操作需要保证一致性
    下订单后需要进行库存扣减、支付,取消订单后需要增加库存、退款等,这三个操作必须全部成功或全部失败才是完整交易。

分布式理论

当我们的单个数据库的性能产生瓶颈的时候,我们可能会对数据库进行分区,这里所说的分区指的是物理分区,分区之后可能不同的库就处于不同的服务器上了,这个时候单个数据库的ACID已经不能适应这种情况了,而在这种ACID的集群环境下,再想保证集群的ACID几乎是很难达到,或者即使能达到那么效率和性能会大幅下降,最为关键的是再很难扩展新的分区了,这个时候如果再追求集群的ACID会导致我们的系统变得很差,这时我们就需要引入一个新的理论原则来适应这种集群的情况,就是CAP原则或者叫CAP定理。

目前较为成熟的保证数据一致性的方法

  • 强一致性:指当一个服务进行了数据操作后,其他关联系统也必须一并完成数据操作。这种模式,对用户来说成功写了什么,就会读到什么。但是根据CAP理论,就会牺牲掉可用性。成熟的技术方案就是通过两阶段(XA协议规定)提交,来完成数据更新。这样除了牺牲了可用性,还会导致事务处理和业务耦合强导致了系统复杂度更高。
  • 弱一致性:服务不保证后续进程或线程获取到最新的值,成熟的技术方案比如利用消息队列来通知后续系统完成数据更新。这种方案目前较为流行,大厂也用的很多。
  • 最终一致性:是若一致性的特定形式。如下订单后,因网络抖动后续系统响应失败,通过定时任务来定期进行后续操作的数据对齐。即使交易出现问题,但最终会保证数据的一致性。

CAP理论

CAP理论提出,服务无法同时满足以下三个属性:

  • 一致性(Consistency):在分布式系统完成某写操作后任何读操作,都应该获取到该写操作写入的那个最新的值。相当于要求分布式系统中的各节点时时刻刻保持数据的一致性。
  • 可用性(Availability):一直可以正常的做读写操作。简单而言就是客户端一直可以正常访问并得到系统的正常响应。用户角度来看就是不会出现系统操作失败或者访问超时等问题。
  • 分区容错性(Partition tolerance):指的分布式系统中的某个节点或者网络分区出现了故障的时候,整个系统仍然能对外提供满足一致性和可用性的服务。也就是说部分故障不影响整体使用。
    事实上我们在设计分布式系统是都会考虑到bug,硬件,网络等各种原因造成的故障,所以即使部分节点或者网络出现故障,我们要求整个系统还是要继续使用的
    (不继续使用,相当于只有一个分区,那么也就没有后续的一致性和可用性了)

具体地讲在分布式系统中,在任何数据库设计中,一个Web应用至多只能同时支持上面的两个属性。显然,任何横向扩展策略都要依赖于数据分区(分区容错性)。因此,设计人员必须在一致性与可用性之间做出选择。

这个定理在迄今为止的分布式系统中都是适用的! 为什么这么说呢?
这个时候有同学可能会把数据库的2PC(两阶段提交)搬出来说话了。OK,我们就来看一下数据库的两阶段提交。
对数据库分布式事务有了解的同学一定知道数据库支持的2PC,又叫做 XA Transactions。
MySQL从5.5版本开始支持,SQL Server 2005 开始支持,Oracle 7 开始支持。
其中,XA 是一个两阶段提交协议,该协议分为以下两个阶段:

  • 第一阶段:事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交.
  • 第二阶段:事务协调器要求每个数据库提交数据。

其中,如果有任何一个数据库否决此次提交,那么所有数据库都会被要求回滚它们在此事务中的那部分信息。这样做的缺陷是什么呢?
这种模式之下我们可以在数据库分区之间获得一致性。
如果CAP 定理是对的,那么它一定会影响到可用性。
如果说系统的可用性代表的是执行某项操作相关所有组件的可用性的和。那么在两阶段提交的过程中,可用性就代表了涉及到的每一个数据库中可用性的和。我们假设两阶段提交的过程中每一个数据库都具有99.9%的可用性,那么如果两阶段提交涉及到两个数据库,这个结果就是99.8%。根据系统可用性计算公式,假设每个月43200分钟,99.9%的可用性就是43157分钟,99.8%的可用性就是43114分钟,相当于每个月的宕机时间增加了43分钟。
以上,可以验证出来,CAP定理从理论上来讲是正确的,CAP我们先看到这里,等会再接着说。

BASE理论

在分布式系统中可用性往往比一致性更加重要,这样就引出了BASE理论,它是对CAP理论的补充。BASE理论指的是:

  • Basically Available(基本可用)
  • Soft state(软状态)
  • Eventually consistent(最终一致性)

BASE理论是对CAP中的一致性和可用性进行一个权衡的结果,理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

解决方案

业务整合-规避分布式事务(强烈不建议使用)

业务整合方案主要采用将接口整合到本地执行的方法。具体就是将A、B、C三个服务整合为一个服务D给到业务,在D服务中来实现单一事务的业务流程服务。

  • 优点:规避了分布式事务
  • 缺点:违背了我们做分布式的初衷。把本来拆分好的业务又耦合在了一起,业务职责不清晰,不利于维护,强烈不建议使用该方案。

eBay模式

此方案核心是将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以通过MQ(推荐)、数据库、本地文件,在通过业务规则或人工发起重试。
消息日志方案核心是需要保证接口的幂等性。
考虑到网络通讯失败、数据丢包等原因,如果接口不能保证幂等性,数据的唯一性将很难保证。

主要思路:
如果产生了一笔交易,需要在交易表增加记录,同时还要修改用户表的金额。这两个表属于不同的远程服务,所以就涉及到分布式事务一致性的问题。
将主要修改操作以及更新用户表的消息放在一个本地事务来完成。同时为了避免重复消费用户表消息带来的问题,达到多次重试的幂等性,增加一个更新记录表updates_applied来记录已经处理过的消息。

  • 第一阶段:A服务,交易表新增数据,通过本地的数据库的事务保障,并把消息放入消息队列。
  • 第二阶段:B服务被消息队列投递消息,B服务收到信息后,通过判断更新记录表updates_applied来检测相关记录是否被执行,未被执行的记录会修改user表,然后增加一条操作记录到 updates_applied,事务执行成功之后再删除队列。

去哪儿网解决方案

蘑菇街解决方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值