分布式的原理

Posted ling-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式的原理相关的知识,希望对你有一定的参考价值。

分布式系统是建立在网络之上的多台计算机这些计算机通过网络协调工作共同完成某个任务的系统。

分布式系统具有以下主要特点

  1. 多台计算机由多台网络连接的计算机组成。
  2. 分布式数据存储数据存放在多台计算机上需要进行分布式数据管理。
  3. 分布式计算任务在多台计算机上共同完成需要进行负载均衡和协调。
  4. 无共享内存多台计算机之间没有共享内存需要通过网络通信实现数据交换。
  5. 分散管理多台计算机有各自的局部管理需要统一起来进行全局管理和协调。
  6. 异步通信计算机之间通过网络进行异步数据交换与远程调用。
  7. 容错性任何一台计算机的故障都不会使系统崩溃需要进行错误处理和容错。
  8. 并发性系统可能同时处理来自不同计算机的多起事件或请求需要进行并发控制。

分布式系统需要解决以下主要问题

  1. 通信协议计算机网络间通信使用的协议HTTPRPC等。
  2. 统一命名在网络中命名计算机、进程、数据等的统一方式。
  3. 数据一致性复制或者分片的数据在多台计算机间的一致性问题。
  4. 并发控制当多个计算机同时访问或操作数据时的协调问题。
  5. 故障恢复当某些计算机发生故障时如何恢复系统运作的问题。
  6. 加载均衡控制任务或请求在不同计算机间的分布充分利用系统资源。
  7. 状态管理管理计算机之间远程调用或长连接的状态信息。

理解分布式系统的原理与实现是后端开发人员很重要的技能通过学习可以理解很多工程化的方案与解决方案。分布式系统也是很多互联网公司考察的重点掌握分布式知识会有很大帮助。

分布式事务原理解析

1. 分布式事务原理解析

1.1. TCC分布式事务

了解过TCC分布式事务的都知道它有三个阶段:try,confirm,cancel,但很多文章就只有原理图,和对原理图的解释,看一遍也留不下印象,这里用实际场景举个例子,说明TCC分布式事务原理

  • try阶段:假设我们又订单系统,它需要调用库存和积分系统,try阶段我们进行的是预处理,比如下单1个商品,在try操作中,我们在库存表设置个冻结字段,表示冻结1个商品,商品的存量先不扣除,而积分表同样添加个预增加积分字段,添加个预积分比如10
  • confirm阶段:我们为什么要经历try阶段?,为了尽可能的保证各个系统都是正常工作的,数据库,服务都没有挂掉,资源没有不足,则可以最大程度上保证confirm阶段能正确执行,confirm阶段也就是正式的扣除库存和增加积分
  • cancel阶段:若try阶段执行错误,则会对前面已经执行的try阶段的系统执行cancel操作,也就是反向SQL回滚,冻结的商品-1,预积分-10。到这里有没有疑问?我首先想到的是若confirm或cancel操作再执行失败怎么办?这里就要由TCC分布式事务框架保证了,它会记录事务活动日志,再confirm或cancel失败后不断尝试调用confirm和cancel的逻辑,所以这里需要开发者自己保证,你的SQL是正确的

TCC分布式框架推荐:ByteTCC,tcc-transaction,himly

1.2. 最终一致性分布式事务

1.2.1. 原理

技术图片

最终一致性方案一般都是有消息中间件来完成的,核心流程如上图所示

  • 假设上游服务为服务A,可靠消息服务为服务B,下游服务为服务C,首选A发送请求给B表示我将要发消息了,你准备下,然后B记录下待确认的数据;
  • A服务正式走完本地数据库逻辑,在发送B确认消息,说我执行完了,你可以确认了,然后B就更新消息的状态为已发送,并把消息发送给MQ
  • 此时服务C订阅了MQ,接收到B通过MQ发送过来的消息,并执行本地数据库操作,在执行完毕后手动ack确认消费完毕,这就走完了全部流程

1.2.2. 问题

下面来考虑这中间会有什么问题了,为什么这样能保证分布式事务的最终一致性?

  • 首先是服务A调用B过程中若不成功或者服务B若没保存待确认消息,那就直接返回的就是失败,还没有操作数据库,所以没有影响
  • A操作数据库和发送确认消息,我们需要放在同一个本地事务中,确保同时成功或失败,这样成功了当然没问题,失败了呢?因为B服务的数据库已经存在待确认消息,可以在B服务开条线程定时判断待确认消息,若发现待确认消息很久没被确认,则主动向A发起请求,判断该操作是否成功了?成功则改状态为已确认,继续执行,失败则删掉该记录
  • B到MQ的过程,若是失败了,MQ挂了之类的,我们可以在B服务后台起个线程,定时判断已确认的消息,在一定时间后是否变成已发送,没有发送的再主动发送
  • 这样后就只剩MQ到C服务了,MQ有重试机制,所以只要业务逻辑没问题,就可以保证最终一致性(这个过程中需要保证MQ到C服务,接口方法需要幂等性)
  • 上述流程需要特别注意的一个点就是MQ,我们需要保证MQ的高可用,否则一旦全部MQ宕机,依赖MQ的分布式事务都不能完成

1.2.3. MQ挂了怎么办

越大的公司,考虑的就越多,任何组件都可能挂掉,MQ如果就一个集群,就要考虑这个集群压力过大到爆掉了怎么办?资金雄厚并发压力大的公司可以直接搞再搞一套备用的,当MQ请求不通后,立即自动切换到备用MQ集群,当然这肯定会造成资源的浪费,毕竟要再搞一套MQ不运行一直放那里,这里再给出一套参考方案(如果你们有redis集群的话)

  • redis有种队列的数据结构,它是可以用来临时充当消息队列的,所以这里要讨论的是,如果用redis当备用方案需要考虑什么问题?
  • 通知机制:当MQ挂了,我们需要将所有用到MQ事务的系统都切换到备用redis方案,所以我们要有个通知机制,本来吗这个类似广播模式的通知应该是MQ完成的,但没了MQ,我们要有其它方案,比如zookeeper的watch机制,zk有监听机制可以通知监听它节点的系统,打开降级开关,达到通知其它系统的效果
  • 消息读取热点问题:我们把消息放到redis的队列会有个对应的key,我们不能把所有消息都放一个key的value中,这样会导致这个value数据量过大;所以这里给出方案:划分上百个队列,对消息hash后放入这些队列,这样尽可能的把消息分散到不同的key
  • 故障的恢复:当我们把MQ恢复过来时,我们也要通知系统,该切换回来了,这个该怎么做呢?可以开启一个线程,每隔一段时间尝试给MQ投递一个消息查看是否恢复,若恢复了,就可以再次通过zookeeper来关闭降级开关

参考:
拜托,面试请不要再问我TCC分布式事务的实现原理!
最终一致性分布式事务如何保障实际生产中99.99%高可用?

以上是关于分布式的原理的主要内容,如果未能解决你的问题,请参考以下文章

Redis分布式锁的原理是啥?如何续期?

分布式事务原理解析

分布式技术专题「分布式协调原理」全流程透析分析Zookeeper的原理实现

Hadoop原理之——HDFS原理

ElasticSearch探索之路分布式原理:分布式路由存储搜索原理

ElasticSearch探索之路分布式原理:分布式路由存储搜索原理