当前位置:首页 > 我是程序员 > 正文

分布式系统的数据一致性问题,你是如何解决的

04-01 我是程序员 Kevin开森


1、一致性概念:
指分布式服务系统之间的弱一致性,包括应用系统的一致性和数据的一致性.
数据量大,高并发要求高,强计算能力,响应速度要求快,等的互联网要求场景下,服务节点开始池化,开始出现容器应用和数据拆分,分而治之的思想和逻辑
水平拆分和垂直拆分

2、解决一致性问题的模式和思路
(1)酸碱平衡理论
①ACID(酸)
原子性,一致性,隔离性,持久性。
关系型数据库事务处理保证强一致性通常是通过多版本控制协议(MVCC)来实现的
下订单和扣库存不一致问题可以将订单和库存放入同一数据库分片,通过关系型数据库事务处理的4个基本要素ACID就可以解决这一不一致问题。

②CAP(帽子原理):分布式系统的CAP原理
一致性,可用性,分区容忍性
分布式的服务系统都需要满足分区容忍性(允许网络上部分消息丢失),但是必须在一致性(所有系统节点在同一时刻读取的数据必须是最新的数据副本)和可用性(好的响应性能,任何故障状态下,服务都会在有限时间内处理完成并进行响应)执行权衡,只能满足以上两点,不能三者兼顾。

③BASE(碱)
BASE思想解决了CAP提出的分布式系统一致性和可用性不可兼得的问题。
BA:基本可用,S:软状态,状态可以在一段时间内不同步,E:最终一致性;
软状态是实现BASE思想的方法,基本可用和最终目标一致是目标;
解决订单和库存的一致性问题,对复杂的分布式事务进行拆解,记录中间所有步骤的软状态,有问题时可以根据记录的状态继续执行任务,达到最终一致;

总结:
向上扩展,升级硬件,使用关系型数据库。
使用开源的关系型数据库,进行水平伸缩和分片,将相关数据分到数据库的同一个分片上,保证事务执行。
如果无法将相关数据分到同一个片上,就需要实现最终一致性,记录事务的软状态。

(2)分布式一致性协议
DTS分布式事务处理模型:
包含四个角色:应用程序,事务管理器,资源管理器和通信管理器
事务管理器是统管全局的管理者(协调者),资源和通信管理器是事务的参与者(参与者)
协调者向参与者发布指令

①两阶段提交协议:
一个准备阶段,一个提交阶段;
存在以下为题:阻塞,单点故障和脑裂问题
保证了系统的强一致性,但是当处理状态处于错误状态,就导致了一致性和可用性不可兼得的问题了

②三阶段协议
解决了阻塞(超时自动提交事务成功)和资源永远锁定的问题
询问阶段,准备阶段,提交阶段

③TCC协议(Try,Confirm,Cancel)推荐这种,以上两种协议高并发系统中基本没有场景用到
简化版的三阶段协议,极端情况下还是会出现不一致和脑裂的问题,好处是具有一定的自我修复能力,任何参与者可自动修复Cancel
先try,没有问题confirm,如果出现问题,执行逆操作Cancel

(3)保证最终一致性模式
①查询模式
任何服务操作都需要提供一个查询接口,用来像外部输出操作执行的状态。服务使用方通过得知操作的执行状态,根据不同状态来做不同的处理操作。
为了实现查询,每个服务操作都需要有唯一的流水号标识,例如请求流水号,订单号等。

②补偿模式
有了上面的查询模式,可以得知具体服务操作的,如果操作处于不正常状态,我们需要修复该操作,通过修复使整个分布式系统达到一致,为了让系统达到一致状态做的努力叫做补偿。

补偿操作分类:
1、自动恢复:程序根据发生的不一致的环境,通过继续进行未完成的操作,或者回滚已经完成的操作,来自动达成一致状态。
2、通知运营
3、技术运营

③异步确保模式
通常把这类操作从主流程中摘除,通过异步的方式进行处理,处理后把结果通过通知系统通知给使用方。最大的好处就是能够对高并发流量进行消峰。
把要执行的异步操作封装后持久入库,然后通过定时捞取未完成的任务进行补偿操作来实现异步确保模式    ,只要定时系统足够健壮,则任何任务最终都会被成功执行。

④定期校对模式
定期校对各系统的操作状态,如果出现不一致状态的操作,则进行补偿操作!
实现定期校对的一个关键就是分布式系统中需要有一个自始至终唯一的ID,生成唯一ID的两种方法:
1、持久性:使用数据库表自增字段或者Sequence生成,为了提高效率,每个应用节点可以缓存一个批次的ID
2、时间型:一般由机器号,业务号,时间,单节点内的自增ID组成。

多应用于金融系统中系统间一致性对账,现金对账,财务对账等

⑤可靠消息模式
1、消息的可靠发送(两种)
业务模块持久化消息发送
和第一种类似,不过持久消息的数据库是独立的,并不耦合在业务系统中

2、消息处理器的幂等性
保证消息一定会发送出去,就需要有重试机制,有重试机制,消息就一定会重复
处理重复问题的最佳方式就是保证操作的幂等性

⑥缓存一致性模式
尽量使用分布式缓存,而不要使用本地缓存
保证弱一致性即可
缓存数据一定要完整,正确

(4)超时处理模式
1、微服务的交互模式
(1)同步调用模式:适用于大规模,高并发的短小请求操作
(2)接口异步调用模式:请求受理,返回受理结果,后面异步返回处理结果
(3)消息队列异步处理模式:利用消息队列作为通信机制,服务2不需要返回处理结果给调用者服务1,调用者只是告诉服务2处理这个事件即可!

2、同步与异步的抉择
尽量使用异步来替换同步操作
能用同步解决的问题,不要引入异步

3、交互模式下超时问题的解决方案
总得来说有两种处理方式:快速失败和内部补偿
(1)同步调用模式下的解决方案
①两状态的同步接口:成功,失败
发现异常超时,快速返回失败
②三状态的同步接口:成功,失败,处理中
发现异常超时,尽可能处理用户发来的请求,状态返回处理中
(2)异步调用模式下的解决方案
(3)消息队列异步处理模式的解决方案
(4)超时补偿的原则
(5)迁移开关的设计

建议使用订单开关:在请求创建的关联体,例如订单,上标记开关,标记是调用老系统还是新系统,而不是通过全局或者配置的开关来判断,避免各个节点之间的开关不同步,不一致,导致既调用老系统,也调用了新系统。

以上是本文的全部内容,希望对大家的学习有帮助,也希望大家多多支持 php自学中心 感谢阅读!