前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式服务架构(二)

分布式服务架构(二)

作者头像
小土豆Yuki
发布2021-07-16 15:28:33
6600
发布2021-07-16 15:28:33
举报
文章被收录于专栏:洁癖是一只狗洁癖是一只狗

ACID

A:原子性

C:一致性

I:隔离性

D:持久性

具有ACID的数据库支持强一致性,强一致性代表数据库本身不会出现不一致的线性,每个事务都是原子性,要么成功,要么失败,事物间具有隔离性,且互不影响,而且最终状态是持久化的。

但是在互联网的时代,项目大多数都是大规模高并发的特性,必须使用拆分理论,对高并发的压力,分而治之,大而化小,小而化了,否则难以支持亿级流量,即使关系型数据库,单机也难以支持存储和吞吐量的性能需求,如果必须要这样做,就应尽量把数据放到数据库一个分片上,这样就可以利用数据库解决不一致的问题,

CAP

C:一致性,在分布式系统中,每一个节点有所有数据的备份,同一时刻具有同样的值,同一时刻读取的数据是一致的,最新的数据

A:可用性,好的响应性能,完全的可用性指的是任何故障下,服务都会在有限时间内处理完并进行相应

P:分区容错行,尽管网络上有部分消息丢失,但是系统仍然可以继续工作。

BASE

BA:Basically Available,基本可用

S:软状态,状态可以在一段时间内不同步

E:Eventually Consistent,最终一致,在一定的时间窗口内,最终数据达成一致即可

软状态是实现BASE的思想的方法,基本可用和最终一致是目的,BASE由于不是强一致性,所以系统会存在短暂不一致的状态,在这个短暂的时间里面,记录每一个操作的临时状态,通过每个临时状态,在系统出现问题的时候,可以通过这个临时状态,可以继续执行或者进行回滚处理,最终达到一致性

解决一致性问题的总结

  • 使用强悍的硬件并运行专业的关系型数据库如oracle,Mysql,能够保证一致性,能够用硬件解决的问题都不是问题
  • 使用强悍的硬件还是成本太高,因此使用关系型数据库进行水平伸缩和扩展,将相关的数据分到数据库的同一个分区,任然可以解决数据一致性问题
  • 由于业务限制,并不能将数据放到一个数据库分片,因此我们记录事务的软状态,如果出现不一致,就可以通过系统自动化或者人工干预修复不一致的问题

分布式一致性协议

二阶段提交协议

  • 准备阶段,协调者向参与者发起指令,参与者评估自己的状态,如果参与者评估自己可以完成,就会写undo或redo,锁定资源,但是不提交
  • 提交阶段,如果每个参与者在准备阶段都返回成功,也就是预留资源和执行操作成功,则协调者向参与者发起提交指令,参与者提交资源变更的事务,释放资源,如果任何一个参与者明确返回准备失败,就是预留资源和执行失败,则协调器发送中止指令,参与者取消已经变更的事务,执行undo日志,释放资源,

二阶段提交在准备阶段锁定资源,这是一个重量级操作,但是能保证强一致性,实现复杂,成本高,不够灵活,

  • 阻塞,任何一次指令都必须收到明确的响应,否则一直阻塞,占用资源不释放
  • 单点故障,若协调者宕机,参与者没有协调者的指挥,就会阻塞,尽管可以选举新的协调者,但是如果协调者发送一个提交指令后宕机,而提交指令仅仅被一个参与者接受,并且参与者接受后也宕机了,则新的协调者也不能处理
  • 脑裂,协调者发送指令,有的参与者接受到了,有的参与者没有接受到,多个参与者出现不一致的状态

三阶段提交

三阶段解决了二阶段一直阻塞的问题,引入了超时机制,并且引入了询问的阶段

  • 询问阶段,协调者就是问问参与者能否完成指令,参与者只要回复可以或不可以,这个阶段超时导致中止,
  • 准备阶段,如果询问都回复可以,那么准备阶段协调者就会发起执行请求,然后写undo,redo日志,执行操作但不提交,如果询问有一个返回不可以,就会发送中止请求,这个阶段超时导致成功。
  • 提交阶段,如果每个参与者才准备阶段成功返回,这协调者就会发送提交操作指令,参与者提交变更的事务,释放资源,若干任何参与者返回失败,则协调者就会发起中止操作,参与者取消变更的事务,执行undo日志,释放资源,

三阶段和二阶段有以下不同

  • 增加了一个询问阶段,为了尽可能早点发现无法执行操作而中止行为,但是只能减少这种情况发生,不能完全避免
  • 在准备阶段,加入了超时机制,一旦超时,协调者和参与者都会继续执行提交事务,默认成功

三阶段协议和二阶段相比,一旦发生超时,系统仍然会发生不一致,但是可以减少这种情况,好处就是不会阻塞和永远锁定资源

TCC协议

不管是二阶段还是三阶段在极端情况下,可能产生阻塞,以及数据不一致的,并且实现比较复杂,此时就提出了TCC协议

TCC分为三个阶段,一个是尝试执行,如果执行没有问题,就会执行confirm,如果执行出现了问题,就会执行cancel操作,看起来和二阶段提交协议没有差别,但是当执行出现问题的时候,有一定的自我修复能力,如果参与者出现了问题,协调者就会通过执行操作的逆操作来达到最终一致性状态,

当然TCC也有许多问题,例如如果有些参与者接收到了请求,有些没有接收到,整个系统然仍处于不一致的,这种情况,往往是自动修复,如果无法修复,就必须有人工参与解决.

保证最终一致性的模式

二阶段和三阶段实现复杂且有的一定的自身问题,TCC,实现协议更简单,容易实现,但是由于每个服务都要进行Try,confirm,和cancel,略显臃肿,因此系统的底线是仅仅需要达到最终一致性,而不是需要实现专业,复杂的一致性协议,实现最终一致性有些非常有效的模式

  1. 查询模式

任何服务操作都需要提供一个查询接口,用来向外部输出操作执行的状态,服务操作的使用方可以通过查询接口得知服务操作执行的状态,然后根据不同状态做不同的处理操作

2.补偿模式

上面的查询模式,在任何情况下,我们可以知道服务的状态,如果整个操作处于不正常状态,则我们需要修正操作中间有问题的子操作,这可能要重新执行未执行的子操作,后者取消已经完成的子操作,通过修复使得整个操作系统达到一致性,为了系统最终达到一致状态而做的努力叫做补偿

补偿分为以下几种

  • 自动恢复,程序根据不一致的环境,通过继续完成未执行的操作,或者回滚已经完成的操作,最终达到一致性
  • 通知运营,如果程序无法自动恢复,并且设计考虑了不一致的场景,则可以提供运营功能,通过手工补偿
  • 技术运营,有些问题,必须要通过技术手段进行修复,包括数据库变更,或者代码变更

3.异步确保模式

对于主流程响应时间要求不太高的场景中,通常把这类操作单独拿出来,通过异步的方式进行处理,然后把结果通知通知系统通知服务使用方。

实践中我们把要执行的异步操作封装后持久化入库,然后通过定时任务捞取任务进行补偿操作实现异步确保模式,只要定时系统足够健壮,则任何任务最重都会被成功执行

4.定时校验模式

在分布式系统中构建了唯一的id,调用链的等基础设施后,我们可以很容易对系统间的不一致进行核对,通常需要第三方的定时核对系统,从第三方监控服务执行的健康程度.

定期校对模式多应用于金融系统,金融系统由于涉及资金安全,需要保证准确性,所以需要多重的一致性保证机制,包括商品交易对账,系统间一致性对账现金对账等,这些都是定期校对模式。

5.可靠消息模式

在分布式系统中,我们经常使用的就是上面提到的异步确认模式,为了让一步操作的调用方和被调用方充分的解耦,采用消息队列,具有可以伸缩性,可分片,可持久化等,

  • 消息的可靠发送 消息的可靠发送认为是尽最大努力发送消息通知,有两种方式

第一种就是上图,发送消息之前就把消息进行持久化,标记为待发送,然后发送消息,如果成功,则将消息标记为发送成功,定时任务定时把未发送的消息并将消息发送

第二种就是上图,和第一种不同就是持久化消息的数据库是独立的,并不耦合在业务系统,发送消息前,先发送一个预发送消息,消息管理模块将其持久化,并标记待发送,在发送成功后,标记消息发送成功,定时任务定时从数据库捞取一定时间内未发送的消息,查询业务系统是否要继续发送,要根据查询结果来确定消息的状态,

超时处理模式

微服务之间通信和交互通过某种协议,然后网络通信是不确定的,我们必须考虑对网络的容错,特定是对调用超时问题的处理

服务之间服务交互模式有三种模式如下

同步调用

异步调用模式

消息队列异步处理模式

交互模式下超时问题的解决方案

  1. 同步模式调用模式的解决方案 服务的处理结果会通过返回值返回给使用方,对返回的状态定义分为两种
    1. 成功和失败
    2. 成功和失败以及处理中

两种状态的同步接口有两种同步超时情况

第一种超时是当调用服务1的时候超时了,此时我们需要使用查询模式,查询处理的结果,获取到结果之后,做出相应的处理,如果成功就继续下面操作,如果失败了就会重试,请求再次处理,但是当查询的结果是异常的,这种情况,服务1实际上没有接受到请求,或者还没有接受到一开始的处理请求,服务适用方需要使用同一个请求id进行重试,当然服务1必须支持幂等性

第二种超时是在服务内部超时的,由于我们前提是只有两种状态,成功和失败,因此这里服务内部使用内部快速失败,同时如果服务2已经接受到了请求,且处理了,则进行回滚操作,否则忽略不做任何处理。

三种状态的同步接口有两种超时情况

三种状态的同步接口超时,服务1超时,和上面两种状态的处理方案一样,而如果服务1调用服务2超时,就不一样了

因为三种状态的同步接口支持中间状态,因此可以返回给使用方一个中间状态,变相的把同步接口变成异步接口,达到最终一致性结果

这种场景下,我们尽最大努力成功处理用户发送的请求,因此服务1调用用服务2超时,我们返回助理中的状态,随后系统尽最大努力补偿执行出错的部分,服务1需要通过服务2的查询结果获取最新的请求处理状态,如果服务2没有明确回复,则可以尝试重新发送请求,服务2也要支持幂等性操作。

2,异步调用模式下解决方案

上图和同步两状态是一样,当服务1超时的时候,我们通过查询来补齐状态,并根据状态完后后续操作,

当内部超时的时候,这和三状态场景相似因此当服务1调用服务2超时,服务1需要根据服务2的最新状态,根据状态补偿后续操作,如果服务2根据最新状态,接受了请求,则继续后续操作,这种和同步三状态不一样的是,一旦处理成功,需要异步回调通知使用方,而三状态只需等待使用方查询,不需要通知,也无法实现,

当在异步返回的时候超时,此时服务1要保证通知一定可送达,如果超时,服务1负责重新继续补偿,通常会实际一个间隔递增的策略,保证通知到使用方.

消息队列异步处理模式解决方案

上面当请求处理,返回受理超时的时候,我可以使用消息可靠发送

当在服务2异步处理超时的时候,消息队列提供两种方式消费消息

  1. 自动增长消费的偏移量,在一个消费者从消费服务器中取走消息后,消队列的消息偏移量自动增加,一旦消息被消费,则不存在服务器中,如果处理失败,也无法从消息服务器中找回
  2. 手工提交偏移量,在一个消费者从消费服务器中取出消息后,先把消息持久化到本地数据库,然后告诉消费服务器已经消费消息,消费服务器才会移除消息,如果持久化失败,则消息任然存在于消费服务器中,消息还可以继续消费
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 洁癖是一只狗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
消息队列 CMQ 版
消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档