一文揭秘DDD到底解决了什么问题(2)

简介: 一文揭秘DDD到底解决了什么问题

1.3.1.2 集群复杂度

让多台机器配合起来达到高性能的目的,是一个复杂的任务,常见的方式有:任务可以指完整的业务处理,也可以指某个具体的任务。1.任务分配:每台机器都可以处理完整的业务任务,不同的任务分配到不同的机器上执行。2.任务分解:业务越来越复杂,单台机器处理的性能会越来越低。为了能够继续提升性能,采用任务分解。

1.3.1.2.1任务分配

image.png

  • 增加一个任务分配器,可以是硬件(F5、交换机)、软件(LVS)、负载均衡软件(Nginx、HAProxy)、自己开发的系统。
  • 任务分配器与业务服务器之间的连接和交互。
  • 任务分配器增加分配算法(轮询、权重、负载)。

业务量继续提升,需要增加任务分配器的数量。

image.png

  • 任务分配器增加为多台,这样需要将不同的用户请求分配到不同的任务分配器上(DNS轮询、智能DNS、CDN、GSLB全局负载均衡)。
  • 任务分配器和业务服务器之间从一对多变成多对多的网状结构。
  • 业务服务器继续扩增,状态管理和故障处理复杂度更大。

1.3.1.2.2 任务分解

微服务架构就采用了这种思路,通过任务分配的方式,能够突破单台机器处理性能的瓶颈,通过增加更多的机器来满足业务的性能需求,但如果业务本身也越来越复杂,单纯只通过任务分配的方式来扩展性能,收益会越来越低。

image.png

通过这种任务分解的方式,能够把原来大一统但复杂的业务系统,拆分成小而简单但需要多个系统配合的业务系统。从业务的角度来看,任务分解既不会减少功能,也不会减少代码量(事实上代码量可能还会增加,因为从代码内部调用改为通过服务器之间的接口调用),任务分解能够提升性能的主要原因是:

1.简单的系统更容易做到高性能:系统的功能越简单,影响性能的点就越少,就更加容易进行有针对性的优化。

2.可以针对单个任务进行扩展:当各个逻辑任务分解到独立的子系统后,整个系统的性能瓶颈更加容易发现,而且发现后只需要针对有瓶颈的子系统进行性能优化或者提升,不需要改动整个系统,风险会小很多。

最终决定业务处理性能的还是业务逻辑本身,业务逻辑本身没有发生大的变化下,理论上的性能是有一个上限的,系统拆分能够让性能逼近这个极限,但无法突破这个极限。

1.3.2 高可用

系统无中断地执行其功能的能力,代表系统的可用性程度,是进行系统设计时的准则之一。

本质上都是通过“冗余”来实现高可用。高可用的“冗余”解决方案,单纯从形式上来看,和高性能是一样的,都是通过增加更多机器来达到目的,但其实本质上是有根本区别的:高性能增加机器目的在于“扩展”处理性能;高可用增加机器目的在于“冗余”处理单元。

通过冗余增强了可用性,但同时也带来了复杂性。

1.3.2.1 计算高可用

计算的特点是无论从哪台机器上进行计算,同样的算法和输入数据,产出的结果都是一样的,所以将计算从一台机器迁移到另一台对业务没有影响。

image.png

  • 需要增加一个任务分配器
  • 任务分配器和真正的业务服务器之间有连接和交互
  • 任务分配器需要增加分配算法(主备【冷备、温备、热备】、主主、多主多倍【2主2备、4主0备】)

1.3.2.2 存储高可用

对于需要存储数据的系统而言,整个系统的高可用设计的难点和关键点在于“存储高可用”。存储和计算的本质区别在于将数据从一台机器搬移到另一台机器时需要通过线路进行传输,而线路传输是存在延迟的,速度在毫秒级别,距离越远,延迟越高。加之各种异常情况(如传输中断、丢包、拥塞),会导致延迟更高。对于高可用系统来说,在某个时间点通信中断就意味着整个系统的数据不一致。按照“数据 + 逻辑 = 业务”的公式,数据不一致将导致最终业务表现不同。如果不做冗余备份,系统的整体高可用性无法保证。因此,存储高可用的难点不在于如何备份数据,而在于如何减少或规避数据不一致对业务造成的影响。

分布式领域内著名的 CAP 定理从理论上证实了存储高可用的复杂度。存储高可用不可能同时满足“一致性、可用性、分区容忍性”,最多只能满足其中两个。因此,在进行架构设计时需要结合业务进行取舍。

1.3.3 可扩展性

可扩展性指系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或者仅需要少量修改就可以支持,无须整个系统重构或者重建。

在软件开发领域,面向对象思想的提出,就是为了解决可扩展性带来的问题;设计模式更是将可扩展性做到了极致。

设计具备良好可扩展性的系统,有两个基本条件:

  • 正确预测变化
  • 完美封装变化

1.3.3.1 预测变化

“唯一不变的是变化”,按照这个标准衡量,架构师每个设计方案都要考虑可扩展性。预测变化的复杂性在于:

  • 不能每个设计点都考虑可扩展性
  • 不能完全不考虑扩展性
  • 所有的预测都存在出错的可能性

如何把握预测的程度和提升预测结果的准确性,是一件很复杂的事情,而且没有通用的标准,更多是靠经验、直觉。

1.3.3.2 应对变化

预测变化是一回事,采取什么方案来应对变化,又是另外一个复杂的事情。即使预测很准确,如果方案不合适,则系统扩展一样很麻烦。

微服务架构中的各层进行封装和隔离也是一种应对变化的解决方式。

1.3.3.2.1 变化层VS稳定层

第一种应对变化的常见方案是将“变化”封装在一个“变化层”,将不变的部分封装在一个独立的“稳定层”。

无论是变化层依赖稳定层,还是稳定层依赖变化层都是可以的,需要根据具体业务情况来设计。

无论采取哪种形式,通过剥离变化层和稳定层的方式应对变化,都会带来两个主要的复杂性相关的问题。

1.系统需要拆分出变化层和稳定层(如何拆分)

2.需要设计变化层和稳定层之间的接口(稳定层接口越稳定越好,变化层接口从差异中找到共同点)

1.3.3.2.2 抽象层VS实现层

第二种常见的应对变化的方案是提炼出一个“抽象层”和一个“实现层”。

抽象层是稳定的,实现层可以根据具体业务需要定制开发,当加入新的功能时,只需要增加新的实现,无须修改抽象层。这种方案典型的实践就是策略模式。

目录
相关文章
|
6月前
|
数据库
DDD架构浅谈
DDD架构浅谈
139 4
|
设计模式 存储 缓存
初探DDD
基于学习《殷浩详解DDD:领域层设计规范》后的动手实践,简单总结,以及个人理解
|
运维 数据挖掘 测试技术
一文揭秘DDD到底解决了什么问题(4)
一文揭秘DDD到底解决了什么问题
101 0
一文揭秘DDD到底解决了什么问题(4)
|
存储 安全 大数据
一文揭秘DDD到底解决了什么问题(3)
一文揭秘DDD到底解决了什么问题
69 0
一文揭秘DDD到底解决了什么问题(3)
|
消息中间件 存储 架构师
一文揭秘DDD到底解决了什么问题(1)
一文揭秘DDD到底解决了什么问题
161 0
|
存储 安全 大数据
DDD到底解决了什么问题
DDD作为架构设计思想帮助微服务控制规模复杂度,那它是怎么做到的呢?
21737 1
DDD到底解决了什么问题
|
存储 设计模式 运维
DDD的关键理解
当我们在学习DDD的过程中,感觉学而不得的时候,可能会问:我们还要学么?这的确引人深思。本文基于工作经验,尝试谈谈对DDD的一些理解。
DDD的关键理解
|
存储 安全 架构师
一文揭秘 DDD 到底解决了什么问题
一文揭秘 DDD 到底解决了什么问题
285 0
|
安全 程序员 微服务
DDD战略战术
DDD开篇总结》[1]的前三篇已经阐述了几个内容 1.DDD是什么2.复杂系统的特征3.DDD如何应对复杂系统4.模型概念5.软件开发流程 但一般DDD资料中都会分为两部分讲述:战略和战术,所以按这两种分类,重新归纳整合一下
371 0
DDD战略战术
|
存储 设计模式 前端开发
浅析 DDD 领域驱动设计(1)
浅析 DDD 领域驱动设计
350 0
浅析 DDD 领域驱动设计(1)