今天开始我们进入架构设计系列中的分布式系统主题部分咯~继续坚持~
前面的几部分介绍了关于软件架构设计的基本概念、基本理论、演化史、常见架构相关的内容,同时还专门介绍了架构设计相关的组织文化保障、遵循定律以及一个程序员应该如何转型成为架构师,此外还应答了朋友们咨询的问题,那就是前端架构和后端架构的区别以及如何提升前端架构设计能力。
本篇开始我们先重点讲解分布式系统架构的前因后果和相关联的内容以及在分布式系统架构设计中的方法论、工具和框架以及一些经典场景的解决方案,欢迎关注!
在当今互联网时代,分布式系统架构成为推动现代软件开发和服务部署的核心理念。
分布式系统在解决单点故障、提高系统可扩展性和确保高可用性方面发挥着至关重要的作用。
随着互联网应用的不断发展,传统的集中式系统面临着越来越多的挑战。单一服务器的性能瓶颈、系统的可维护性、服务的高可用性等问题愈发凸显。分布式系统架构的出现,为解决这可问题提供了新的思路和技术方案。
分布式系统是指多台计算机通用网络协同工作,共同完成一个系统的设计、实现和运行。分布式系统的核心在于将系统的各个组成部分分散到不同的节点上,通用网络进行通信和协同工作,从而形成一个整体的系统。
分布式系统在当今互联网时代具备极大的重要性,主要体现在以下几个方面:
分布式系统能够将服务分散到多个节点,当一个节点发生故障时,其他节点依旧可以提供服务,从而确保系统的高可用性和容错性。
随着企业业务的增长,分布式系统可以通过添加更多的节点来实现横向扩展,提高系统的性能和负载能力。
分布式系统能够更有效地利用资源,分摊压力,提高整体效率,这包括计算资源、存储资源和网络资源等。
分布式系统采用模块化设计,组件之间相对独立,便于维护和升级,同时也可以更容易适应不同的业务需求和变化
接下来的内容将会研究分布式系统的各个方面,涵盖关键技术、设计原则、实际应用案例等,帮助大家一起更好地理解和应用分布式系统。
在背景部分的定义部分已经讲了分布式系统的定义,再一起回顾下:
分布式系统是由多台计算机通用网络连接,协调完成一个共同的任务或提供一个服务的系统。在分布式系统中,各个计算机节点相互协作,共同为用户提供服务,形成一个统一的、虚拟的系统。
从对分布式系统的概念研究上,可以看到,它具备以下特性:
分布式系统中的多个节点可以并行地执行任务,提高了系统整体的并发性能。
由于网络延迟、节点故障等原因,分布式系统中的节点之间的通信是不确定的,也同时增加了系统的复杂性。
分布式系统通过透明性隐藏了底层的网络和计算机节点细节,使得用户感受不到系统的分布式特性。
由于网络的不确定性,实现全局一致性成为分布式系统架构设计中的难点和挑战。
随着数据规模的增大,单一计算机处理效率下降,分布式系统通过分散数据存储和计算,提高了系统的处理能力。
分布式系统通过将服务分布到多个节点,即使某个节点发生故障,其他节点依旧能提供服务,提高系统的可用性。
分布式系统能够通过增加节点来实现横向扩展,应对业务的快速增长
分布式系统采用模块化设计,组件之间相对独立,便于维护和升级,增加了系统的灵活性。
从对分布式系统的概念进行分析,针对他的显著特点以及存在的一些挑战,需要针对分布式系统进行专业的架构设计,那这个思考设计的过程,它是要遵循分布式系统的基本设计理论的。
CAP 理论是分布式系统架构设计中的基本原则,它明确说明在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容忍性(Partition Tolerance)三者不可兼得,在读写数据场景中,只能保证两个,另外一个必须被舍弃。
要求所有节点在同一时刻能看到相同的数据,如果一个节点对数据进行了更新,那其他节点读取到的也应该是更新后的数据。
要求在任何请求中,系统都能够返回一个非错误的响应,在这个要求下,并没有要求一定是得到正确的结果,但是不能超时、不能出错。
要求即使系统中出现网络分区部分节点之间的通信终端,系统依旧可以继续运行,并且可以持续提供功能服务,履行其系统职责。
CAP 理论给出了三者只能选择两者的设计原则建议,但是在分布式系统实际设计的过程中,和这个建议是会存在一些偏差的。
系统使用网络提供服务,因为网络本身是无法做到 100% 可靠,那 P 是一个必然的选择,在这个前提下,就只能再选择一个 C 或者 A 了,因此在具体实践中,不太可能出现 CA 的组合,只存在 CP 组合或者 AP 组合。
如上图所示,选择 CP 组合,为了保证数据一致性,在服务节点 1 和服务节点 2 上有一份数据因为网络等原因,导致版本不一致,分别为 V2.0 和 V1.0 ,此时用户端访问服务节点 2, 因为数据未到最新的 V2.0,在 CP 组合的设计原则指导下,此时需要对用户端的请求报错,舍弃 A。
如上图所示,为了保证 A,同样是服务节点 1 和服务节点 2 因为网络等原因导致数据版本不一致,针对用户端请求,是需要服务节点 2 把不一致的数据版本 V1.0 返回给用户端的,此时丧失了 C,这就是 AP 组合的设计思想。虽然数据版本还是 V1.0,但是不影响它正常返回正确结果(结合实际场景虽然是不合理的数据)。
从上述 CP 组合和 AP 组合流程的分析,不难看出,CAP 所聚焦的并不是整个系统,而是在系统中流转处理的数据。而在我们实际系统设计的场景中,一个系统承载的数据类型是复杂多样的,针对不同类型的数据可能在 CP、AP 的选择是不一样的,因此在具体设计的时候不要把 CAP 限制在系统层面,而是要落到具体的数据场景中。
比如在 AI 数据标注服务系统的场景中,标注员信息、标注项目管理信息等场景类型的数据选择 AP 组合即可,但是对流转中的标注任务数据,是要选择 CP 组合的。
之所以选择一个相对小领域的数据标注场景,是因为笔者当前在这个领域的公司就职,用实际工作的场景对自己部门的同事们更有贴切的体感。
BASE 理论是对传统 ACID 原则的一种补充,它更适应分布式系统的思想。指基本可用(Basically Available)、软状态(Soft State)、最终一致性(Eventual Consistency),核心思想是即使数据无法做到强一致性(CAP 中的 C),但应用可以采用适合的方式到达最终一致性。
是指系统出现故障时,依旧能够保证基本的可用性,不要求所有可用性,可舍弃部分可用性。比如平时我们经常说的,要保障核心主流程可用。
在这个要求的指导下,是需要架构师在设计架构的时候,明确各个业务范围和重要性,即在极端情况下,可以牺牲哪个业务场景,又要死保哪个业务场景。这是一个非常有困难极具挑战的任务。
比如在我们设计数据标注系统的时候,会降项目管理的基本功能作为次要功能,而标注工具的操作和标注的主流程就是我们要死保的功能。
是指系统的状态可以有一段时间的不一致,系统会在一定时间内达到一致状态。
是指系统保证在一段时间内,所有副本的数据都会达到一致状态。
比如在我们设计的数据标注系统中,当标注员针对一份点云数据进行标注时,可能会出现成千上万个 Label,我们需要实时统计他的工作量,当前我们选择了在工程侧通用 Kafka 通道连接大数据技术体系,在大数据技术域中进行转换计算等工作,但是如果出现网络延迟、代码问题会出现实时流程丢失极少量数据的情况导致工作量的不准确,结合实际业务场景,工作量的实时指标仅做参考,最终决定结算流程的是项目完成后的最终统计数据。因此,我们设计了离线数据回补流程和项目结束后的数据对账流程,来保证用于结算的数据最终在完成的那一刻是一致准确的。
从两个理论的讲解上可以推导出 BASE 理论实际是对 CAP 理论中 AP 组合的一个补充理论。
从严格意义上,因为网络延迟的存在,在那极端的延迟实践间隔中,是无法达到真正的 CP 的,而我们在实际选择 CP 组合设计数据场景方案的时候,往往是符合 BASE 理论中最终一致性的要求。而非实时一致性。
AP 组合舍弃了 C,但它不是不要 C,而是一段时间后达到 C,所以 AP 组合它也是要求的最终一致性。
从上述对 CP 和 AP 组合和 BASE 理论的关系,我们可以得出结论:在分布式系统中,严格意义上讲,是追求保障数据的最终一致性。
ACID 是数据库管理系统为了保证事务的一个理论,包括四个要求:
要求在一个事务中的所有操作,要么全部执行完成,要么全部都不完成,不会在中间过程中结束。事务在处理过程中一旦发生错误就会被回滚到初始状态。
要求在事务开始前和结束后,数据的完整性不被破坏。
要求在多个并发事务执行时,保证交叉执行不会互相影响,导致数据的不一致。在事务隔离级别上分为:读未提交(Read uncommitted)、读提交(Read committed)、可重复读(Repeatable read)、串行化(Serializable)。
要求在事务结束后,不管什么条件下,哪怕系统崩了,对数据的修改都是持久化的。
此处我命名为设计模式,但是此设计模式非彼设计模式。这里我所讲的分布式架构设计模式,是指在构建、维护和演进分布式系统时遇到的常见问题的常用场景解决方案。俗称基于经验总结,经过行业实践验证,有助于提高分布式系统的性能、可伸缩性和可靠性。
下面会对常用的模式进行简单的介绍说明以及它所适用的场景:
这是一种现在比较典型的分布式系统架构模式,客户端和服务器通过网络进行通信,客户端发送请求,服务端响应请求并返回结果。
它适用于需求相对明确、资源分工相对明确的业务场景。
在这个模式里面,有一个住节点负责数据写操作,多个从节点从主节点复制数据,负责数据读操作,和 前面讲的常见软件架构中 CQRS 有类似的味道,但这个模式在分布式系统中,往往是指在数据库层面的架构设计方法。
它适用于读操作非常频繁,写操作相对少的业务场景,该场景下通过多个读节点来提高系统的读取性能。
但在该模式下存在单点故障的严重风险,一旦主节点宕机会导致整个系统不可用。
将系统数据分为多个分区,每个分区独立管理,来提高系统的扩展性和并发现。
它适用与大规模数据和用户的场景,比如我们常见的分布式数据库或者分布式文件系统就是典型的分区模式。
将系统划分为多个层次,每个层次负责特定的功能,有清晰的职责定义和边界划分,来提高系统的可维护性和可扩展性。比如经典的 MVC 三层架构、COLA 的四层架构。
它适用于复杂系统,通过分层降低系统的耦合度,使得不同层次的组件能够独立变更。
微服务模式是一种将应用程序划分为一组小型的并且相互独立的服务,每个服务独立部署独立发布,独立运行在自己的进程中。
它适用于需要高度可扩展性和独立部署的场景,允许使用不同技术栈。
它是通过哈希函数将数据分布到多个节点中,使得新增或删除节点时影响最小。
它适用于需要频繁扩展和缩减节点的场景,比如负载均衡。
事件驱动是通过事件的产生、传递和响应来实现系统之间的松耦合。
它适用于降低系统间依赖性,提高系统弹性的场景。
该模式确保在分布式系统中只有一个节点充当零担这,其他节点均为从节点。
它适用于需要有序执行的场景,比如分布式锁的实现机制。
该模式确保在所有节点上执行相同的状态机,保持系统的一致性。
它适用于需要一致性和可靠性的场景,比如分布式数据库。
用于快速检查一个元素是否属于一个集合,用以减轻数据库或存储系统的负担。
它适用于高效判断某个元素是否存在的场景,比如缓存系统。
反熵模式通过引入额外的信息熵来提高系统的可用性。
它适用于降低系统熵值,减少系统混乱的场景,比如故障诊断系统。
裂脑模式是指在分布式系统中,由于网络分区导致节点之间无法通信,可能导致不一致。
它适用于需要考虑网络分区问题的场景,提高系统的鲁棒性。