什么是分布式系统

252 阅读7分钟

分布式系统的定义

分布式系统指的是由一组通过网络进行通信,为了完成共同的任务而协调工作的计算机节点组成的系统。

分布式系统解决了什么问题

  1. 分布式系统解决了单机性能瓶颈导致的成本问题
  2. 解决了用户量和数据量爆炸性地增大导致的成本问题
  3. 满足了业务高可用的要求。互联网产品对于停止服务等故障是无法容忍的。如果想要提供高可用的服务,唯一的方式就是通过增加冗余来完成。那么就算是单机系统可以支撑的服务,因为要满足高可用的要求,也会变成一个分布式系统。
  4. 分布式系统解决了大规模软件系统的迭代效率和成本的问题。

可以总结出在互联网时代,单机系统是无法解决成本、效率和高可用问题的

分布式系统是怎么解决单机系统面临的成本、效率和高可用的问题

  • 分布式系统指的是由一组通过网络进行通信,为了完成共同的任务,而协调工作的计算机节点组成的系统
  • 将一些廉价的 PC 机,通过网络连接起来共同完成工作,并且在系统中提供冗余节点,来解决高可用的问题。

分布式系统的引入带来的新问题

分布式系统的引入了分布式系统内部工作节点的协调问题,主要体现在分布式系统内部组件、实例之间,通过异步网络进行通信和协调的问题上。

分布式计算

分布式系统内部的协调需要做以下的工作

其一:怎么找到服务

在分布式系统内部,会有不同的服务(角色),服务 A 怎么找到服务 B 是需要解决的问题。一般来说,服务注册与发现机制是常用的思路。

其二:怎么找到实例

在找到服务之后,当前的请求应该发往服务的哪一个实例呢?一般来说

  • 如果同一个服务的实例是完全对等的(无状态),那么按负载均衡的策略来处理就足够(轮询、权重、Hash、一致性Hash,FAIR 等各种策略的适用场景)。

  • 如果同一个服务的实例不对等(有状态),那么就需要通过路由服务(元数据服务等)先确定,当前要访问的请求数据做到哪一个实例上,然后再进行访问。

其三:怎么管理配置

在分布式系统内部,会有不同的服务(角色),每一个服务都有多个实例,并且还可能自动扩容和缩容。在这样的情况下,通过配置文件的方式,来管理配置是低效、易出错的,对于这个问题,一般的思路是通过一个中心化的存储来统一管理系统的配置,即配置中心。

其四:怎么进行协同

在单体系统中,所有的功能模块都在一个进程中,系统内部进行协同非常简单, 直接调用系统的API 加锁就可以了。但是在分布式系统中,由于不同的功能模块已经拆分为不同的服务,并且一般都运行在不同的机器上,这个时候系统中加锁相关 API 就不能使用了。对于这个问题,我们可以通过一个跨进程与机器的分布式锁来解决。

其五:怎么确保请求只执行一次

在分布式系统中,各个模块之间通过网络进行连接。如果出现了网络抖动等情况,会导致模块之间的调用失败,而调用失败就有可能触发重试策略,使得程序可能出现没有执行或者多次执行的情况。一般来说,重试加上幂等是分布式系统中,确保请求只执行一次的方法。

其六:怎么避免雪崩

系统雪崩是指由于正反馈循序导致不断扩大规则的故障。一次雪崩通常是由于整个系统中,一个很小的部分出现故障而引发,进而导致系统的其他部分也出现故障。比如,系统中某一个服务的一个实例出现故障,导致负载均衡将该实例摘除,从而引起其他实例负载升高,最终导致该服务的所有实例像多米诺骨牌一样,一个一个全部出现故障。

主要是两个思路

  • 一个是快速失败和降级机制(熔断、降级、限流等),通过快速减少系统负载来避免雪崩的发生;
  • 另一个是弹性扩容机制,通过快速增加系统的服务能力来避免雪崩的发生。

我们可以根据不同的场景做出不同的选择,或者两个策略都使用。

一般来说,快速失败会导致部分的请求失败,如果分布式系统内部,对一致性要求很高的话,快速失败会带来系统数据不一致的问题。这种情况下,弹性扩容会是一个比较好的选择,但是弹性扩容的实现成本比快速失败要大,响应时间也更长。

其七:怎么监控告警和故障恢复

对于一个分布式系统来说,如果我们不能清楚地了解内部的状态,那么系统的稳定性是没有办法完全保障的。所以我们一定要完善分布式系统的监控(比如接口的时延和可用性等信息),分布式追踪 Trace ,模拟故障的混沌工程以及相关的告警等机制。同时做好故障恢复预案,确保在故障发生的时候,能够快速恢复故障。

分布式存储

首先分布式计算的协调方式在分布式存储中同样适用。

数据分片:单机系统是不可能存储所有数据的,所以需要解决怎么将数据按一定的规则,分别存储到不同的机器上。这就是数据分片。常用的方案是:Hash 和 Region 分片的策略。

数据复制:为了满足系统的高可用要求,需要对数据做冗余处理,这就是数据复制,有的地方叫做副本。

目前的方案主要为:中心化方案(主从复制、一致性协议,比如 Raft 和 Paxos 等)和去中心化的方案( Quorum 和 Vector Clock)。

分布式事务:对于分布式系统来说,要实现事务,首先需要对并发事务进行排序的能力,这样在事务冲突的时候,就可以确认哪个事务提交成功,哪个事务提交失败。

如何处理分布式系统引入的,内部工作节点的协调问题,把它们总结为下面三类问题。

  • 首先是路由问题,分布式系统由单体系统拆分而来,必然会导致分布式系统内部,出现复杂的路由问题。路由问题主要是解决分布式系统内部各服务和实例之间的通信,

    • 我们可以将“怎么找到服务”和“怎么找到实例”等服务注册发现和负载均衡的问题,理解为正常情况下的路由问题,
    • 将“怎么做数据分片”的问题,理解为带状态的路由问题,
    • 将“怎么避免雪崩”涉及的熔断、降级等快速失败和降级机制,理解为异常情况下的路由问题。
  • 接下来是共识问题,分布式系统的各个组件是运行在不同机器上的不同进程,因为程序总是需要按一定的逻辑有序地执行,所以需要一个办法,来协调分布式系统内部,已经各自为政的服务和实例,而共识就是讨论并解决这一类问题的,例如“怎么做数据复制”、“怎么做分布式事务”和“怎么做分布式锁”里,都会涉及共识问题。

  • 最后是运维问题,分布式系统相对于单体系统是非常碎片化的,如果还依靠人肉运维,在效率上是完全行不通的,所以催生了一系列自动化运维的工具和平台来解决这一类问题,例如“怎么管理配置”和“怎么监控告警和故障恢复”都涉及运维的问题。